获取十进制数的整数和小数部分

Ham*_*med -1 c# floating-point numbers

鉴于X.Y,我想得到XY

例如,鉴于123.456我想得到123456NOT 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
Run Code Online (Sandbox Code Playgroud)

参考文献

如上所述,使用这种方法我会得到0.456,而我需要456. 当然我可以做到以下几点:

int fractionalNums = (int)((num - Math.Truncate(num)) * 1000); 

// fracionalNums = 456
Run Code Online (Sandbox Code Playgroud)

此外,此方法需要知道给定的十进制数有多少个小数,以便您可以乘以该数字(例如,123.456有 3、123.4567有 4、123.456789有 6、123.1234567890123456789有 19)。

需要考虑的几点:

  • 此操作将执行数百万次;因此,性能至关重要(也许基于位的解决方案会更好);
  • 精度至关重要,不能接受任何四舍五入。

注 1

出于性能原因,我对基于字符串操作的方法不感兴趣。


笔记2

我的问题中的数字是decimal类型的,因此仅适用于decimal类型并且失败floatdouble(由于浮点精度)的方法是可以接受的。


注 3

小数的两侧(即整数部分和小数部分)可以认为是两个整数。因此,123.000456不是预期的输入;并且即使给出,也可以将其拆分为123and 456(因为两边都被认为是整数)。

Bac*_*cks 5

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));
Run Code Online (Sandbox Code Playgroud)

  • @Hamed `Math.Pow` 的性能更差。此外,您可以将 10、100、1000... 存储在数组中,完全不浪费时间 (4认同)
  • @MohamadArmoon:这也说明了人们可能怀疑您的问题的一个原因。123.456 和 123.4560000000001 在数学上非常接近,但它们产生非常不同的输出。这表明您正在做的事情在许多情况下都没有意义。 (2认同)