我试图将数字四舍五入到小数点后7位,但是我注意到Math.Round在某些数字上无法正常工作:
Math.Round(39.248779999999996,3) => 39.249
Math.Round(39.248779999999996,4) => 39.2488
Math.Round(39.248779999999996,5) => 39.248779999999996
Math.Round(39.248779999999996,6) => 39.248779999999996
Math.Round(39.248779999999996,7) => 39.248779999999996
谁能向我解释这种行为?
最佳答案
如果需要精度,请使用decimal
而不是double
/ float
;
var num = 39.248779999999996; // num is double.
var num = 39.248779999999996m; // num is decimal.
十进制关键字表示128位数据类型。相比
浮点类型,十进制类型具有更高的精度和
范围较小,因此适合金融和货币
计算。
编辑:
您can't完全以浮点数/双精度数表示所有数字:
只要知道什么,二进制浮点算术就可以
继续,不要期望值正好是您的小数
放在您的程序中,不要期望涉及二进制的计算
浮点数必须产生精确的结果。即使
两个数字都准确地表示在您使用的类型中,
涉及这两个数字的运算结果不一定
准确地表示出来。用除法最容易看出这一点(例如
尽管1和10都是正好,但1/10不能精确表示
可表示),但任何操作都可能发生-甚至表面上
无辜的,例如加法和减法。
例如:
double doubleValue = 1f / 10f; // => 0.10000000149011612
decimal decimalValue = 1m / 10m; // => 0.1
您可以截断数字以确保最多7个数字,但不能精确舍入该值:
double value = 39.248779999999996;
double roundTo = Math.Pow(10, 7);
double resultResult = Math.Truncate(value * roundTo) / roundTo;
// result is : 39.2487799
关于c# - C#Math.Round bug?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/38029183/