我已经阅读了很多与浮点数相关的内容,但它们都过于复杂。我认为我已经基本理解了,但是还有一件事我想确定:
我知道形如 1/pow(2,n)
的分数可以在浮点数中精确表示,其中 n
是整数。这意味着如果我将 1/32
加上自身 3200 万次,那么结果将精确等于 1,000,000
。
那么像 1/(32+16)
这样的表达式呢?它是两个二的幂次方之和的倒数,它能行吗?或者是 1/32+1/16
行吗?这就是我困惑的地方,如果有人能为我澄清一下,我将不胜感激。
我已经阅读了很多与浮点数相关的内容,但它们都过于复杂。我认为我已经基本理解了,但是还有一件事我想确定:
我知道形如 1/pow(2,n)
的分数可以在浮点数中精确表示,其中 n
是整数。这意味着如果我将 1/32
加上自身 3200 万次,那么结果将精确等于 1,000,000
。
那么像 1/(32+16)
这样的表达式呢?它是两个二的幂次方之和的倒数,它能行吗?或者是 1/32+1/16
行吗?这就是我困惑的地方,如果有人能为我澄清一下,我将不胜感激。
1/(32 + 16)
在二进制中无法表示,因为分母中有一个因子3。但是1/32 + 1/16 = 3/32
可以表示。double
中,你只有53位的尾数,所以1/2 + 1/2^500
无法表示。将这个推广到其他进制:
如果分母的质因数分解只包含2和5,那么一个数在十进制中可以被精确表示。
如果有理数X
的分母的质因数分解只包含在进制N
的质因数分解中出现的质数,那么X
可以在进制N
中被精确表示。
1.m * 2^e
其中1.m
是一个二进制小数,e
是一个正整数或负整数。
因此,您可以精确地表示1/32 + 1/16
,如下:
1.1000000 * 2^-4
(1.10
是二进制分数等于1.5。)1/48
在这种格式下无法表示。
1.m * 2^e
。) - huon1.1000000 * 2^-4
吗? - mkeiser还有一点尚未提及的是,从语义上讲,浮点数可能最好被视为表示一系列值的范围。这个值的范围有一个非常精确定义的中心点,IEEE规范通常要求浮点计算的结果是包含原始数字中心点操作得到的点的范围内的数字,但顺序如下:
double N1 = 0.1; float N2 = (float)N1; double N3 = N2;
N2是正确的单精度表示,它明确地表示了在N1中所表示的值,尽管该语言要求使用显式转换。N3将表示N2可以表示的值之一(语言规范恰好选择了其范围以float
的范围中间为中心的double
值)。请注意,虽然N2表示其类型的值包含正确的值,但N3却不是。
顺便提一下,在 .net 和 .net 语言中将字符串转换为浮点数时,似乎会经过一个中间转换到 double
的步骤,这可能有时会改变值。例如,即使值 13571357 可以表示为单精度浮点数,但值 13571357.499999999069f 会被四舍五入为 13571358(尽管它显然更接近于 13571357)。
double
到float
而不是不幸允许的float
到double
,那么将float
转换为double
会是一件好事。 其中一个原因是,如果允许隐式转换long
->Decimal
->double
->float
,则可以指定,在内置类型中,从T到U到V的任何隐式转换序列都等同于从T直接到V的隐式转换。 允许从float
到double
的隐式转换会破坏这一点。 - supercat
Y
是2的幂次方且X
是小于2的53次方的数字,我就可以使用任何数字X/Y
吗? - Niet the Dark Absol