这就是我想要实现的目标:
如果双精度数的小数位数超过 3 位,我想截断第三位以外的所有小数位。 (不要圆形。)
Eg.: 12.878999 -> 12.878
如果双精度数少于 3 位小数,则保持不变
Eg.: 125 -> 125
89.24 -> 89.24
我遇到了这个命令:
double example = 12.34567;
double output = Math.Round(example, 3);
但我不想四舍五入。根据上面发布的命令,
12.34567 -> 12.346
我想截断该值,使其变为:
12.345
双精度数没有小数位 - 它们不是基于小数位开始的。您可以获得“截断为三位小数时最接近当前值的双精度值”,但它仍然不完全相同。你最好使用
decimal
。
话虽如此,如果只是舍入发生的方式有问题,您可以使用
Math.Truncate(value * 1000) / 1000;
,它 may 可以做您想要的事情。 (听上去,你根本不需要 rounding。)不过,它仍然可能是“狡猾的”,因为结果仍然不会真正只有三位小数。然而,如果你用十进制值做同样的事情,它会工作:
decimal m = 12.878999m;
m = Math.Truncate(m * 1000m) / 1000m;
Console.WriteLine(m); // 12.878
编辑:正如 LBushkin 指出的那样,您应该清楚出于 display 目的而截断(通常可以在格式说明符中完成)和为了进一步计算而截断(在这种情况下,上述方法应该有效)。
我想不出在显示目的之外明确失去精度的原因。在这种情况下,只需使用字符串格式即可。
double example = 12.34567;
Console.Out.WriteLine(example.ToString("#.000"));
double example = 3.1416789645;
double output = Convert.ToDouble(example.ToString("N3"));
乘以 1000,然后使用 截断,然后除以 1000。
如果您截断数字的目的是出于显示原因,那么您只需在将双精度数转换为字符串时使用适当的格式即可。
像
String.Format()
和 Console.WriteLine()
(以及其他)这样的方法允许您限制格式化值的精度位数。
尝试“截断”浮点数是不明智的 - 浮点数在许多情况下没有精确的十进制表示形式。应用诸如放大数字、截断数字、然后缩小数字之类的方法可以轻松地将值更改为与您对“截断”值的预期完全不同的值。
如果您需要数字的精确十进制表示,您应该使用
decimal
而不是 double
或 float
。
您可以使用:
double example = 12.34567;
double output = ( (double) ( (int) (example * 1000.0) ) ) / 1000.0 ;
上面的答案很好 - 如果您正在寻找可重用的东西,这里就是代码。请注意,您可能想要检查小数位值,这可能会溢出。
public static decimal TruncateToDecimalPlace(this decimal numberToTruncate, int decimalPlaces)
{
decimal power = (decimal)(Math.Pow(10.0, (double)decimalPlaces));
return Math.Truncate((power * numberToTruncate)) / power;
}
在 C 语言中:
double truncKeepDecimalPlaces(double value, int numDecimals)
{
int x = pow(10, numDecimals);
return (double)trunc(value * x) / x;
}
迟到了 2024 年的讨论。真的很惊讶没有人提到 Math.Round():
https://learn.microsoft.com/en-us/dotnet/api/System.Math.Round?view=net-8.0
Math.Round(0.12367, digits: 3); //0.124
Math.Round(0.12367, digits: 3, MidpointRounding.ToZero); //0.123