C#Math.Round错误?

时间:2016-06-25 13:45:36

标签: c# math rounding

我正在尝试将数字舍入到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

有人能解释一下这种行为吗?

1 个答案:

答案 0 :(得分:4)

如果您需要精确度,请使用decimal而非double / float;

var num = 39.248779999999996; // num is double.
var num = 39.248779999999996m; // num is decimal.
  

decimal关键字表示128位数据类型。相比   浮点类型,十进制类型具有更高的精度和a   较小的范围,这使其适合金融和货币   计算

修改

can't完全代表float / double中的所有数字:

  

二进制浮点运算只要你知道是什么就可以了   继续,不要指望值正好是十进制的   放入你的程序,不要指望涉及二进制的计算   浮点数必然产生精确的结果。即使   两个数字都在你正在使用的类型中精确表示,   涉及这两个数字的操作的结果不一定   完全代表。这是最容易看到的分裂(例如   尽管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