计算机是否开始正确存储0.1?

Ima*_*mad -3 c# floating-point precision ieee-754

在学习浮点运算时,我发现了一些东西,我引用:'浮点数/双精度不能精确存储0.1".

SO上有一个问题指向同一件事,接受的答案也很有说服力.但是我想在我自己的计算机上试一试,所以我写下面的程序如下

double a = 0.1;

if (a == 0.1)
{
    Console.WriteLine("True");
}
else
{
    Console.WriteLine("False");
}

Console.Read();
Run Code Online (Sandbox Code Playgroud)

和控制台打印True.令人震惊,因为我已经说服了别的东西.任何人都可以告诉我浮点运算是怎么回事?或者我只有一台将数值存储为10的计算机?

Jon*_*eet 7

你的程序只检查编译器是否以相同的方式两次逼近0.1,就像它一样.

a不是0.1,你不检查它是否 0.1.您正在检查"最接近的可表示值为0.1"是否等于"最接近的可表示值为0.1".

您的代码有效地编译为:

double a = 0.1000000000000000055511151231257827021181583404541015625;

if (a == 0.1000000000000000055511151231257827021181583404541015625)
{
    Console.WriteLine("True");
}
else
{
    Console.WriteLine("False");
}
Run Code Online (Sandbox Code Playgroud)

...因为0.1000000000000000055511151231257827021181583404541015625是double最接近0.1 的值.

有时你可以看到一些非常奇怪的效果.虽然double定义为64位IEEE-754编号,但C#规范允许中间表示使用更高的精度.这有时意味着将值分配给一个字段可以改变结果的简单行为-甚至是铸造一个值,该值已doubledouble.

在您提到的问题中,我们并不真正知道如何获得原始值.问题是:

我有一个叫做的双变量x.在代码中,x获得的值为0.1

我们并不确切地知道它是如何赋值0.1的,这​​个细节很重要.我们知道这个值不会精确到 0.1,所以涉及到什么样的近似值?例如,考虑以下代码:

using System;

class Program
{
    static void Main()
    {
        SubtractAndCompare(0.3, 0.2);
    }

    static void SubtractAndCompare(double a, double b)
    {
        double x = a - b;
        Console.WriteLine(x == 0.1);
    }
}
Run Code Online (Sandbox Code Playgroud)

x大约为0.1,但它与"最接近double0.1的值"不完全相同.在这种情况下,它恰好小于0.1 - 该值恰好是0.09999999999999997779553950749686919152736663818359375,它不等于0.1000000000000000055511151231257827021181583404541015625 ...因此比较打印为False.