我试图将数字四舍五入到小数点后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/

10-14 12:01
查看更多