计算机是否开始正确存储 0.1?
Have computers started storing 0.1 correctly?
在学习浮点运算时,我遇到了一些事情,我引用:'a float/double can't store 0.1 precisely"。
SO 上有一个question 指向相同的东西并且被接受的答案也很有说服力。但是我想在我自己的电脑上试试,所以我写了下面的程序
double a = 0.1;
if (a == 0.1)
{
Console.WriteLine("True");
}
else
{
Console.WriteLine("False");
}
Console.Read();
控制台打印 True
。令人震惊,因为我已经对其他事情深信不疑。谁能告诉我浮点运算是怎么回事?或者我刚得到一台以 10 为基数存储数值的计算机?
您的程序只是检查编译器是否以相同的方式逼近 0.1 两次,确实如此。
a
的值不是 0.1,您没有检查它是否 是 0.1。您正在检查 "the closest representable value to 0.1" 是否等于 "the closest representable value to 0.1".
您的代码有效编译为:
double a = 0.1000000000000000055511151231257827021181583404541015625;
if (a == 0.1000000000000000055511151231257827021181583404541015625)
{
Console.WriteLine("True");
}
else
{
Console.WriteLine("False");
}
... 因为 0.1000000000000000055511151231257827021181583404541015625 是最接近 0.1 的 double
值。
有时您仍然可以看到一些非常奇怪的效果。虽然 double
被定义为 64 位 IEEE-754 数字,但 C# 规范允许中间表示使用更高的精度。这意味着有时为字段赋值的简单行为可能会改变结果 - 甚至将已经是 double
的值转换为 double
.
在你提到的问题中,我们并不知道原始值是如何得到的。问题指出:
I've a double variable called x
. In the code, x
gets assigned a value of 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);
}
}
x
的值大约为 0.1,但与 "the closest double
value to 0.1" 的近似值并不完全相同。 In this case it happens to be slightly less than 0.1 - the value is exactly 0.09999999999999997779553950749686919152736663818359375, which isn't equal to 0.1000000000000000055511151231257827021181583404541015625... so the comparison prints False.
在学习浮点运算时,我遇到了一些事情,我引用:'a float/double can't store 0.1 precisely"。
SO 上有一个question 指向相同的东西并且被接受的答案也很有说服力。但是我想在我自己的电脑上试试,所以我写了下面的程序
double a = 0.1;
if (a == 0.1)
{
Console.WriteLine("True");
}
else
{
Console.WriteLine("False");
}
Console.Read();
控制台打印 True
。令人震惊,因为我已经对其他事情深信不疑。谁能告诉我浮点运算是怎么回事?或者我刚得到一台以 10 为基数存储数值的计算机?
您的程序只是检查编译器是否以相同的方式逼近 0.1 两次,确实如此。
a
的值不是 0.1,您没有检查它是否 是 0.1。您正在检查 "the closest representable value to 0.1" 是否等于 "the closest representable value to 0.1".
您的代码有效编译为:
double a = 0.1000000000000000055511151231257827021181583404541015625;
if (a == 0.1000000000000000055511151231257827021181583404541015625)
{
Console.WriteLine("True");
}
else
{
Console.WriteLine("False");
}
... 因为 0.1000000000000000055511151231257827021181583404541015625 是最接近 0.1 的 double
值。
有时您仍然可以看到一些非常奇怪的效果。虽然 double
被定义为 64 位 IEEE-754 数字,但 C# 规范允许中间表示使用更高的精度。这意味着有时为字段赋值的简单行为可能会改变结果 - 甚至将已经是 double
的值转换为 double
.
在你提到的问题中,我们并不知道原始值是如何得到的。问题指出:
I've a double variable called
x
. In the code,x
gets assigned a value of 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);
}
}
x
的值大约为 0.1,但与 "the closest double
value to 0.1" 的近似值并不完全相同。 In this case it happens to be slightly less than 0.1 - the value is exactly 0.09999999999999997779553950749686919152736663818359375, which isn't equal to 0.1000000000000000055511151231257827021181583404541015625... so the comparison prints False.