计算器如何精确工作?
我想知道计算器如何精确地工作。例如,当以双精度计算时,sin(M_PI) 的值并不完全为零:
#include <math.h>
#include <stdio.h>
int main() {
double x = sin(M_PI);
printf("%.20f\n", x); // 0.00000000000000012246
return 0;
}
现在,当用户输入 sin(π) 时,我当然希望打印零。我可以轻松地在 1e-15 的某个地方进行舍入,以使这个特定的情况起作用,但这是一个 hack,而不是一个解决方案。当我开始像这样舍入并且用户输入类似 1e-20 的内容时,他们会得到零(因为舍入)。当用户输入 1/10 并重复按下 = 键时,也会发生同样的情况 - 当他达到舍入阈值时,他会得到零。
然而,一些计算器会为 sin(π) 返回纯零,同时它们可以轻松地使用 (1e–20)/10 等表达式。窍门在哪里?
I wonder how calculators work with precision. For example the value of sin(M_PI)
is not exactly zero when computed in double
precision:
#include <math.h>
#include <stdio.h>
int main() {
double x = sin(M_PI);
printf("%.20f\n", x); // 0.00000000000000012246
return 0;
}
Now I would certainly want to print zero when user enters sin(π). I can easily round somewhere on 1e–15 to make this particular case work, but that’s a hack, not a solution. When I start to round like this and the user enters something like 1e–20, they get a zero back (because of the rounding). The same thing happens when the user enters 1/10 and hits the = key repeatedly — when he reaches the rounding treshold, he gets zero.
And yet some calculators return plain zero for sin(π) and at the same time they can work with expressions such as (1e–20)/10 comfortably. Where’s the trick?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
桌面计算器使用任意精度的数学库。这些可以配置为具有高得多的精度。手持计算器(传统专用计算器和移动电话)使用固定精度数学库。
如果您想精确打印零,请使用宽度说明符
Desktop Calculators use arbitrary precision math libraries. Those can be configured to have much higher precision that double. Handheld calculators (tradition dedicated and mobile phones) use fixed precision math libraries.
If you want to print exactly zero, use width specifier
可以在此计算器精度页面上找到一些答案。
解决方案包括:
Some answers can be found on this Calculator Precision page.
Among solutions are:
正如已经说过的,诀窍可能是计算器将使用任意精度数学库或查找表。
我还要补充一点,由于使用 浮点 算术,您的代码片段会以这种方式工作正如您可能知道的那样,这不是真正的数学,因为它不精确 -
1.0 + 0.1 != 1.1
(实际上是 1.1000000000000001):)The trick is probably, as already said, that calculators will use arbitrary precision math libraries or lookup tables.
I'd also add that your code snippet works that way due to using floating point arithmetics, which as you probably know is not true math in the sense it's not precise -
1.0 + 0.1 != 1.1
(it's actually 1.1000000000000001) :)他们可能正在使用查找表来加速三角公式。在这种情况下,效果很好的特殊数字可能就在表中。
They may be using a lookup table to speed up their trig formulas. In that case the special numbers that work out nicely would probably just be in the table.