谷歌计算器故障,浮动与双倍可能是一个原因吗?

The Google Calculator Glitch, could float vs. double be a possible reason?

提问人:mauriciopastrana 提问时间:8/26/2008 最后编辑:Stephen Ostermillermauriciopastrana 更新时间:9/8/2023 访问量:2578

问:

由于谷歌新发现的无法正确地进行数学运算(根据谷歌的说法),我想我应该尝试用 C 语言运行以下方法来运行一点理论。500,000,000,000,002 - 500,000,000,000,001 = 0

int main()
{
   char* a = "399999999999999";
   char* b = "399999999999998";

   float da = atof(a);
   float db = atof(b);

   printf("%s - %s = %f\n", a, b, da-db);
  
   a = "500000000000002";
   b = "500000000000001";
   da = atof(a);
   db = atof(b);
   printf("%s - %s = %f\n", a, b, da-db);
}

 

运行此程序时,将获得以下信息

   399999999999999 - 399999999999998 = 0.000000
   500000000000002 - 500000000000001 = 0.000000

似乎 Google 正在使用简单的 32 位浮点精度(此处出现错误),如果您在上面的代码中将浮点数切换为 double,则可以解决问题!难道是这样吗?

c 数学 google-search

评论


答:

4赞 Frank Krueger 8/26/2008 #1

有关更多此类愚蠢行为,请参阅这篇与 Windows 计算器有关的好文章。

当你改变内部时,没有人会注意到

Calc 的内部结构 - 算术 引擎 - 完全被扔掉了 并从头开始重写。这 标准IEEE浮点库 替换为 任意精度算术 图书馆。这是在人们之后完成的 不停地写哈哈的文章 Calc 无法进行十进制算术 正确地,例如计算 10.21 - 10.2 的结果为 0.01000000000000016。

2赞 DrPizza 8/26/2008 #2

似乎 Google 正在使用简单的 32 位浮点精度(此处出现错误),如果您在上面的代码中将浮点数切换为 double,则可以解决问题!难道是这样吗?

不,你只是推迟问题。双打仍然表现出同样的问题,只是数字更大。

2赞 gil 8/26/2008 #3

在 C# 中,尝试 ,你会得到,但这就是它应该的样子(double.maxvalue == (double.maxvalue - 100))true

考虑一下,您有 64 位表示大于 () 的数字,因此预计会不准确。2^64double.maxvalue

1赞 Derek Park 8/26/2008 #4

@ebel

考虑一下,您有 64 位表示大于 2^64 (double.maxvalue) 的数字,因此预计会不准确。

2^64 不是双精度的最大值。2^64 是双精度值(或任何其他 64 位类型)可以容纳的唯一值数。 等于 1.79769313486232e308。Double.MaxValue

浮点数的不准确性不是来自表示大于的值(这是不可能的,不包括)。它来自这样一个事实,即所需的值范围太大而无法适应数据类型。因此,我们放弃了精度,以换取更大的有效范围。从某种意义上说,我们正在删除有效数字以换取更大的指数范围。Double.MaxValueDouble.PositiveInfinity

@DrPizza

甚至没有;IEEE 编码对相同的值使用多个编码。具体来说,NaN 由全位 1 的指数表示,然后是尾数的任何非零值。因此,双打有 252 个 NaN,单打有 223 个 NaN。

真。我没有考虑重复的编码。不过,双打实际上有 2 个52-1 NaN,单打有 2个 23-1 NaN。:p

0赞 DrPizza 8/27/2008 #5

2^64 不是双精度的最大值。2^64 是双精度值(或任何其他 64 位类型)可以容纳的唯一值数。Double.MaxValue 等于 1.79769313486232e308。

甚至没有;IEEE 编码对相同的值使用多个编码。具体来说,NaN 由全位 1 的指数表示,然后是尾数的任何非零值。因此,双打有 252 个 NaN,单打有 223 个 NaN。

0赞 DrPizza 8/27/2008 #6

真。我没有考虑重复的编码。不过,双打实际上有 252-1 NaN,单打有 223-1 NaN。:p

哎呀,忘了减去无穷大。

0赞 John Meagher 9/13/2008 #7

我了解到的此问题的粗略估计版本是 32 位浮点数为您提供 5 位精度,而 64 位浮点数为您提供 15 位精度。当然,这将根据浮点数的编码方式而有所不同,但这是一个很好的起点。