鉴于X.Y
,我想得到X
和Y
。
例如,给定123.456
,我想得到123
和456
(不 0.456
)。
我可以执行以下操作:
decimal num = 123.456M;
decimal integer = Math.Truncate(num);
decimal fractional = num - Math.Truncate(num);
// integer = 123
// fractional = 0.456 but I want 456
但是,如上所述,使用这种方法我将得到0.456
,而我需要456
。当然,我可以执行以下操作:
int fractionalNums = (int)((num - Math.Truncate(num)) * 1000);
// fracionalNums = 456
但是,此方法需要知道给定十进制数字有多少个小数,以便您可以乘以该数字(例如123.456
有三个,123.4567
有四个,123.456789
有六个,123.1234567890123456789
有19个。)
要考虑的几点:
出于性能原因,我对任何基于字符串操作的方法都不感兴趣;请不要推荐这种方法。
我的问题中的数字为decimal
类型,并且方法仅适用于decimal
类型,并且在float
或double
上失败(由于浮点精度)是可以接受的。
小数点的两侧(即整数和小数部分)可以视为两个整数。因此,123.000456
永远不会受到挑战,即使给出了挑战,也可以将其拆分为123
和456
(因为双方都被视为整数)。
答案 0 :(得分:4)
BitConverter.GetBytes(decimal.GetBits(num)[3])[2];
-逗号后的位数
long[] tens = new long[] {1, 10, 100, 1000, ...};
decimal num = 123.456M;
int iPart = (int)num;
decimal dPart = num - iPart;
int count = BitConverter.GetBytes(decimal.GetBits(num)[3])[2];
long pow = tens[count];
Console.WriteLine(iPart);
Console.WriteLine((long)(dPart * pow));
答案 1 :(得分:1)
十进制的尾数为96位,因此 long 不足以获取所有可能的值。
定义为十进制定义的所有10(正)次幂:
decimal mults[] = {1M, 1e1M, 1e2M, 1e3M, <insert rest here>, 1e27M, 1e28M};
然后,在循环内部,您需要获取小数位数(将“尾数”除以10的幂乘以 以获得小数的标称值):
int[] bits = Decimal.GetBits(n);
int scale = (bits[3] >> 16) & 31; // 567.1234 represented as 5671234 x 10^-4
decimal intPart = (int)n; // 567.1234 --> 567
decimal decPart = (n - intPart) * mults[scale]; // 567.1234 --> 0.1234 --> 1234
答案 2 :(得分:-1)
最简单的方法可能是将数字转换为字符串。 然后取小数点后的子串,再转回int。