浮点运算太可靠了
我知道现代计算机系统中执行的浮点算术并不总是与实际算术一致。我正在尝试设计一个小型 C# 程序来演示这一点。例如:
static void Main(string[] args)
{
double x = 0, y = 0;
x += 20013.8;
x += 20012.7;
y += 10016.4;
y += 30010.1;
Console.WriteLine("Result: "+ x + " " + y + " " + (x==y));
Console.Write("Press any key to continue . . . "); Console.ReadKey(true);
}
但是,在这种情况下,x
和 y
最终是相等的。
我是否可以使用类似复杂性的程序来演示浮点运算的不一致性,而不使用任何真正疯狂的数字?如果可能的话,我希望避免数学上正确的值超出小数点以上几位。
I understand that floating point arithmetic as performed in modern computer systems is not always consistent with real arithmetic. I am trying to contrive a small C# program to demonstrate this. eg:
static void Main(string[] args)
{
double x = 0, y = 0;
x += 20013.8;
x += 20012.7;
y += 10016.4;
y += 30010.1;
Console.WriteLine("Result: "+ x + " " + y + " " + (x==y));
Console.Write("Press any key to continue . . . "); Console.ReadKey(true);
}
However, in this case, x
and y
are equal in the end.
Is it possible for me to demonstrate the inconsistency of floating point arithmetic using a program of similar complexity, and without using any really crazy numbers? I would like, if possible, to avoid mathematically correct values that go more than a few places beyond the decimal point.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
备注:基于此,不要假设 .NET 中的浮点运算不可靠。
Remark: based on this don't make the assumption that floating point arithmetic is unreliable in .NET.
这是一个基于先前问题的示例,该示例演示了浮点算术的计算结果并不完全按照您的想象。
在这种情况下,
false
会打印到屏幕上。为什么?因为数学的执行位置与 int 类型转换的执行位置不同。对于 x,数学在一个语句中执行并存储到 f,然后将其转换为整数。对于 y,计算值在转换之前不会被存储。 (在 x 中,计算和转换之间会丢失一些精度,而 y 则不然。)有关浮点数学中具体发生的情况背后的解释,请参阅此问题/答案。 为什么不同C# 中用括号分隔和用语句分隔时的浮点精度?
Here's an example based on a prior question that demonstrates float arithmetic not working out exactly as you would think.
In this case,
false
is printed to the screen. Why? Because of where the math is performed versus where the cast to int is happening. For x, the math is performed in one statement and stored to f, then it is being cast to an integer. For y, the value of the calculation is never stored before the cast. (In x, some precision is lost between the calculation and the cast, not the case for y.)For an explanation behind what's specifically happening in float math, see this question/answer. Why differs floating-point precision in C# when separated by parantheses and when separated by statements?
我最喜欢的演示可以归结为“
输出是不是
0
”。My favourite demonstration boils down to
The output is not
0
.尝试使其小数点不是 0.5。
在这里查看这篇文章
http://floating-point-gui.de/
Try making it so the decimal is not .5.
Take a look at this article here
http://floating-point-gui.de/
尝试将非常大数和非常小数相加。小的将被消耗,结果将与大的相同。
try sum VERY big and VERY small number. small one will be consumed and result will be same as large number.
尝试对无理数(例如平方根)或非常长的重复分数执行重复运算。您很快就会发现错误不断累积。例如,计算 1000000*Sqrt(2) 与 Sqrt(2)+Sqrt(2)+...+Sqrt(2)。
Try performing repeated operations on an irrational number (such as a square root) or very long length repeating fraction. You'll quickly see errors accumulate. For instance, compute 1000000*Sqrt(2) vs. Sqrt(2)+Sqrt(2)+...+Sqrt(2).
我现在能想到的最简单的是:
The simplest I can think of right now is this:
我建议,如果您真的感兴趣,请看一下讨论浮点数的许多页面中的任何一个,其中一些页面非常详细。您很快就会意识到,在计算机中,它们是一种折衷方案,以精度换取范围。如果您要编写使用它们的程序,您确实需要了解它们的局限性以及如果您不小心可能会出现的问题。这将是值得您花时间的。
I suggest that, if you're truly interested, you take a look any one of a number of pages that discuss floating point numbers, some in gory detail. You will soon realize that, in a computer, they're a compromise, trading off accuracy for range. If you are going to be writing programs that use them, you do need to understand their limitations and problems that can arise if you don't take care. It will be worth your time.
double
精确到约 15 位数字。您需要更高的精度才能真正开始仅通过几个浮点运算来解决问题。double
is accurate to ~15 digits. You need more precision to really start hitting problems with only a few floating point operations.