地板行为,编号为1.9999999999999999d

时间:2017-09-18 12:41:39

标签: c# floor

看看这种情况:

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。

为什么会这样?

2 个答案:

答案 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}}有关,并决定编译器对给定文字使用什么值。