Вы можете попробовать 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-битный мантисса (пожалуйста, обратите внимание, абсент из parts[2]
, который мы игнорировали ), поэтому long Significand
является слишком коротким (long
является 64-разрядным * только 1019 *)
Демо-версия:
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