看看这种情况:
var number1 = Math.Floor(1.9999999999999998d); // the result is 1
var number2 = Math.Floor(1.9999999999999999d); // the result is 2
在两种情况下,结果应为1.我知道这是一种非常不可能的情况,但可能会发生。使用Math.Truncate
方法和(int)
投射相同的ocurr。
为什么会这样?
答案 0 :(得分:0)
很多数字都没有确切的double
表示。
离double
最近的1.9999999999999999
数字是2
,因此编译器对其进行舍入。
在使用Math.Floor
功能之前尝试打印它!
但是,距离1.9999999999999998
最近的地方仍为1.something
,因此Floor
会发出1
。
同样,在函数Floor
之前打印数字就足以看到它们实际上不再是在代码中输入的数字。
编辑:以最精确的方式打印出数字:
double a1 = 1.9999999999999998;
Console.WriteLine(a1.ToString("G17"));
// output : 1.9999999999999998
double a2 = 1.9999999999999999;
Console.WriteLine(a2.ToString("G17"));
// output : 2
由于双精度并不总是精确到17个有效数字(包括小数点前的第一个),因此默认ToString()
会将其四舍五入到16位有效数字,因此,在这种情况下,将其四舍五入到2
也是,但仅在运行时,而不是在编译时。
答案 1 :(得分:-1)
如果您将文字值放入另一个变量,那么您会看到它的原因:
var a1 = 1.9999999999999998d; // a1 = 1.9999999999999998d
var number1 = Math.Floor(a1);
Console.WriteLine(number1); // 1
var a2 = 1.9999999999999999d; // a2 = 2
var number2 = Math.Floor(a2);
Console.WriteLine(number2); // 2
至于为什么 - 这必须 与double
的{{3}}有关,并决定编译器对给定文字使用什么值。