我正在尝试解析 C# decimal
类型为我自己的 Decimal
类型,其类型为{{1 }}和significant
。我尝试过:
exponent
但是我认为它会很慢。
答案 0 :(得分:0)
您可以尝试decimal.GetBits(),例如
public static MyType.Decimal FromDecimal(decimal decimalValue) {
int[] parts = decimal.GetBits(decimalValue);
int sign = 1 - 2 * (parts[3] >> 31 & 1);
long mantissa = ((((long)parts[1]) << 32) | (((long)parts[0]))) * sign;
int exponent = -((parts[3] >> 16) & 0xFF);
return MyType.Decimal() {
Significand = mantissa,
Exponent = exponent
};
}
但是要小心:decimal
使用 96位尾数(请注意,我们{em>忽略了parts[2]
的 abscence < / em>),这就是long Significand
太短(long
仅 64位)
演示:
decimal[] tests = new decimal[] {
0m,
10m,
100m,
0.01m,
123e-1m,
-3m,
123456789e4m,
123456789e-4m,
1234567890123456m,
1234567890123456e4m // 12345678901234560000 > long.MaxValue (9223372036854775807)
};
string report = string.Join(Environment.NewLine, tests
.Select(test => {
int[] parts = decimal.GetBits(test);
int sign = 1 - 2 * (parts[3] >> 31 & 1);
long mantissa = ((((long)parts[1]) << 32) | (((long)parts[0]))) * sign;
int exponent = -((parts[3] >> 16) & 0xFF);
return $"{test,20} == {mantissa}e{exponent}";
}));
结果:
0 == 0e0
10 == 10e0
100 == 100e0
0.01 == 1e-2
12.3 == 123e-1
-3 == -3e0
1234567890000 == 1234567890000e0
12345.6789 == 123456789e-4
1234567890123456 == 1234567890123456e0
12345678901234560000 == -350295040e0 -- mantissa is 96 bit, doesn't fit 64-bit long