Google计算器故障,可能是浮动还是两倍?
我这样做只是为了踢(所以,不完全是一个问题,我已经可以看到下降的趋势了),但是,代替Google的新发现的无法正确进行数学运算(检查它!根据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
解决方案
回答
有关这种愚蠢的更多信息,请参阅有关Windows计算器的这篇不错的文章。
当我们改变内部时,没人会注意到
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.
回答
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?
不,我们只是推迟这个问题。双打仍然显示相同的问题,只是数字更大。
回答
在C#中,尝试(double.maxvalue ==(double.maxvalue 100)),我们将得到true ...
但这就是应该的样子:
http://en.wikipedia.org/wiki/Floating_point#Accuracy_problems
考虑到这一点,我们有64位表示一个大于2 ^ 64(double.maxvalue)的数字,因此不准确。
回答
@ebel
thinking about it, you have 64 bit representing a number greater than 2^64 (double.maxvalue), so inaccuracy is expected.
2 ^ 64不是两倍的最大值。 2 ^ 64是双精度型(或者任何其他64位类型)可以容纳的唯一值的数量。 Double.MaxValue`等于1.79769313486232e308.
浮点数的不准确性并非来自于表示大于Double.MaxValue的值(这是不可能的,不包括Double.PositiveInfinity)。这是因为所需的取值范围太大而无法放入数据类型。因此,我们放弃了精度以换取更大的有效范围。本质上,我们将大范围的数字作为交换以降低指数范围。
@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.
真的。我没有考虑重复的编码。不过,实际上双打有252-1 NaN,单打有223-1 NaN。 :p
回答
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.
甚至不; IEEE编码对相同的值使用多种编码。具体来说,NaN用全比特-1的指数表示,然后用尾数的任何非零值表示。因此,双打有252个NaN,单打有223个NaN。
回答
True. I didn't account for duplicate encodings. There are actually 252-1 NaNs for doubles and 223-1 NaNs for singles, though. :p
h,忘了减去无穷大。
回答
我了解到的此问题的粗略估算版本是32位浮点数为我们提供5位精度,而64位浮点数为我们提供15位精度。当然,这取决于浮点数的编码方式,但这是一个很好的起点。