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

问题描述 投票:0回答:7

我这样做只是为了好玩(所以,不完全是一个问题,我可以看到已经发生了向下修改)但是,代替谷歌新发现的inabilitymath正确(检查一下!根据google 500,000,000,000,002 - 500,000,000,000,001 = 0),我想我应该在 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,则可以解决问题!可以是这个吗?

/mp

c math google-search
7个回答
4
投票

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

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

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


2
投票

在 C# 中,尝试 (double.maxvalue == (double.maxvalue - 100)) ,你会得到 true ...

但这就是它应该的样子:

http://en.wikipedia.org/wiki/Floating_point#Accuracy_problems

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


2
投票

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

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


1
投票

@玉宝

考虑一下,您有 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


0
投票

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

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


0
投票

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

哦,忘记减去无穷大了。


0
投票

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

© www.soinside.com 2019 - 2024. All rights reserved.