Math.Floor行为

Alp*_*ğlu -3 .net c#

double c, d, e;
double a = (c - d) / e;
double b = Math.Floor(a);
Debug.WriteLine(a.ToString() + " " + b.ToString());
Run Code Online (Sandbox Code Playgroud)

上面的代码在一个配置中输出"3 2",其中所有数字都是双倍的.这怎么可能?是因为双重操作导致的分数误差?但是我认为a.ToString()应该用整数来表示整数.

Jon*_*eet 10

这只是一个问题double.ToString().这是一个简短但完整的程序,展示了同样的事情:

using System;

public class Test
{
    static void Main(string[] args)
    {
        // Find the largest double less than 3
        long bits = BitConverter.DoubleToInt64Bits(3);
        double a = BitConverter.Int64BitsToDouble(bits - 1);
        double b = Math.Floor(a);
        // Print them using the default conversion to string...
        Console.WriteLine(a.ToString() + " " + b.ToString());
        // Now use round-trip formatting...
        Console.WriteLine(a.ToString("r") + " " + b.ToString("r"));
    }
}
Run Code Online (Sandbox Code Playgroud)

输出:

3 2
2.9999999999999996 2
Run Code Online (Sandbox Code Playgroud)

现在double.ToString()记录在:

此版本的ToString方法隐式使用当前区域性的通用数字格式说明符("G")和NumberFormatInfo.

...和通用数字格式说明符 docs状态:

精度说明符定义可以出现在结果字符串中的最大有效位数.如果省略精度说明符或为零,则数字类型将确定默认精度,如下表所示.

...表格显示默认精度为double15.如果您认为2.9999999999999996四舍五入为15位有效数字,则最终为3.

事实上,这里的确切价值a是:

2.999999999999999555910790149937383830547332763671875
Run Code Online (Sandbox Code Playgroud)

...当被视为15位有效数字时,再次为3.