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

发布于 2024-07-04 13:11:51 字数 1264 浏览 9 评论 0原文

由于 Google 新发现无法执行数学 正确 (检查一下!根据 Google 500,000,000,000,002 - 500,000,000,000,001 = 0< /code>),我想我应该在 C 中尝试以下操作来运行一些理论。

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位浮点精度(这里的错误),如果你在上面的代码中将float切换为double,你就可以解决问题! 会是这样吗?

With Google's newfound inability to do math correctly (check it! according to Google 500,000,000,000,002 - 500,000,000,000,001 = 0), I figured I'd try the following in C to run a little theory.

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);
}

 

When you run this program, you get the following

   399999999999999 - 399999999999998 = 0.000000
   500000000000002 - 500000000000001 = 0.000000

It would seem like Google is using simple 32 bit floating precision (the error here), if you switch float for double in the above code, you fix the issue! Could this be it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

背叛残局 2024-07-11 13:11:51

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

The rough estimate version of this issue that I learned is that 32-bit floats give you 5 digits of precision and 64-bit floats give you 15 digits of precision. This will of course vary depending on how the floats are encoded, but it's a pretty good starting point.

岁月静好 2024-07-11 13:11:51

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

哦,忘记减去无穷大了。

True. I didn't account for duplicate encodings. There are actually 252-1 NaNs for doubles and 223-1 NaNs for singles, though. :p

Doh, forgot to subtract the infinities.

篱下浅笙歌 2024-07-11 13:11:51

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

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

Calc 的内部结构 - 算术
发动机 - 被完全扔掉
并从头开始重写。 这
标准 IEEE 浮点库
被替换为
任意精度算术
图书馆。 这是人们之后完成的
继续写关于如何的哈哈文章
Calc 无法进行小数算术
正确地,例如计算
10.21 - 10.2 结果为 0.0100000000000016。

For more of this kind of silliness see this nice article pertaining to Windows calculator.

When you change the insides, nobody notices

The innards of Calc - the arithmetic
engine - was completely thrown away
and rewritten from scratch. The
standard IEEE floating point library
was replaced with an
arbitrary-precision arithmetic
library. This was done after people
kept writing ha-ha articles about how
Calc couldn't do decimal arithmetic
correctly, that for example computing
10.21 - 10.2 resulted in 0.0100000000000016.

一个人的夜不怕黑 2024-07-11 13:11:51

2^64 不是 double 的最大值。 2^64 是 double(或任何其他 64 位类型)可以保存的唯一值的数量。 Double.MaxValue 等于 1.79769313486232e308。

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

2^64 is not the maximum value of a double. 2^64 is the number of unique values that a double (or any other 64-bit type) can hold. Double.MaxValue is equal to 1.79769313486232e308.

Not even; the IEEE encodings use multiple encodings for the same values. Specifically, NaN is represented by an exponent of all-bits-1, and then any non-zero value for the mantissa. As such, there are 252 NaNs for doubles, 223 NaNs for singles.

风筝有风,海豚有海 2024-07-11 13:11:51

@玉宝

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

2^64 不是 double 的最大值。 2^64 是 double(或任何其他 64 位类型)可以保存的唯一值的数量。 Double.MaxValue 等于 1.79769313486232e308。

浮点数的不准确性并非来自于表示大于 Double.MaxValue 的值(这是不可能的,不包括 Double.PositiveInfinity)。 这是因为所需的值范围太大,无法适应数据类型。 所以我们放弃精度来换取更大的有效范围。 从本质上讲,我们正在删除有效数字以换取更大的指数范围。

@DrPizza

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

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

@ebel

thinking about it, you have 64 bit representing a number greater than 2^64 (double.maxvalue), so inaccuracy is expected.

2^64 is not the maximum value of a double. 2^64 is the number of unique values that a double (or any other 64-bit type) can hold. Double.MaxValue is equal to 1.79769313486232e308.

Inaccuracy with floating point numbers doesn't come from representing values larger than Double.MaxValue (which is impossible, excluding Double.PositiveInfinity). It comes from the fact that the desired range of values is simply too large to fit into the datatype. So we give up precision in exchange for a larger effective range. In essense, we are dropping significant digits in return for a larger exponent range.

@DrPizza

Not even; the IEEE encodings use multiple encodings for the same values. Specifically, NaN is represented by an exponent of all-bits-1, and then any non-zero value for the mantissa. As such, there are 252 NaNs for doubles, 223 NaNs for singles.

True. I didn't account for duplicate encodings. There are actually 252-1 NaNs for doubles and 223-1 NaNs for singles, though. :p

眼泪都笑了 2024-07-11 13:11:51

看起来Google正在使用简单的32位浮点精度(这里的错误),如果你在上面的代码中将float切换为double,你就可以解决问题! 可以是这个吗?

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

It would seem like Google is using simple 32 bit floating precision (the error here), if you switch float for double in the above code, you fix the issue! Could this be it?

No, you just defer the issue. doubles still exhibit the same issue, just with larger numbers.

枯叶蝶 2024-07-11 13:11:51

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

想想看,您有 64 位表示大于 2^64 (double.maxvalue) 的数字,因此不准确是意料之中的。

In C#, try (double.maxvalue == (double.maxvalue - 100)), you'll get true but that's what it is supposed to be.

Thinking about it, you have 64 bit representing a number greater than 2^64 (double.maxvalue), so inaccuracy is expected.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文