Math 什么类型的数字可以用二进制浮点表示?
我读过很多关于浮动的书,但都是不必要的。我想我已经完全明白了,但有一件事我想确定: 我知道,形式为Math 什么类型的数字可以用二进制浮点表示?,math,language-agnostic,floating-point,Math,Language Agnostic,Floating Point,我读过很多关于浮动的书,但都是不必要的。我想我已经完全明白了,但有一件事我想确定: 我知道,形式为1/pow(2,n)的分数,加上n一个整数,可以用浮点数精确表示。这意味着,如果我将1/32添加到自身3200万次,我将得到确切的1000000 像1/(32+16)这样的东西怎么样?它是二的二次幂之和的一,这行吗?或者是1/32+1/16有效吗?这就是我感到困惑的地方,如果有人能为我澄清这一点,我将不胜感激。规则可以总结为: 如果分母的素因式分解仅包含2,则一个数字可以用二进制精确表示。(即分母
1/pow(2,n)
的分数,加上n
一个整数,可以用浮点数精确表示。这意味着,如果我将1/32
添加到自身3200万次,我将得到确切的1000000
像
1/(32+16)
这样的东西怎么样?它是二的二次幂之和的一,这行吗?或者是1/32+1/16
有效吗?这就是我感到困惑的地方,如果有人能为我澄清这一点,我将不胜感激。规则可以总结为:
- 如果分母的素因式分解仅包含2,则一个数字可以用二进制精确表示。(即分母是二的幂)
1/(32+16)
不能用二进制表示,因为它的分母中有一个因子3。但是1/32+1/16=3/32
也就是说,在浮点类型中需要表示更多的限制。例如,IEEEdouble
中只有53位尾数,因此1/2+1/2^500
是不可表示的
所以,只要指数的范围不超过53次幂,你就可以做2次幂的和
要将其推广到其他基础:
- 如果分母的素因式分解仅由2和5组成,则数字可以精确地以10为基数表示
- 如果
分母的素数分解只包含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
不可在此格式中表示。尚未提及的一点是,从语义上讲,浮点数最好被视为表示一系列值。值的范围有一个非常精确定义的中心点,IEEE规范通常要求浮点计算的结果是一个数字,其范围包含一个将在原始数字的中心点上运行的点,但顺序如下:
double N1 = 0.1;
float N2 = (float)N1;
double N3 = N2;
双N1=0.1;
浮点数N2=(浮点数)N1;
双N3=N2;
N2是N1中表示的值的明确正确的单精度表示,尽管该语言愚蠢地要求使用显式转换。N3将表示N2可以表示的一个值(语言规范恰好选择了double
值,其范围集中在float
范围的中间)。请注意,虽然N2表示其范围包含正确值的类型的值,但N3不表示
顺便说一句,在.net和.net语言中,数字从字符串到浮点的转换似乎要经过到
double
的中间转换,这有时可能会改变值。例如,即使值13571357可以表示为单精度浮点,值13571357.499999909069F也会四舍五入到13571358(尽管它显然更接近13571357)当且仅当某些整数M和e等于M•2e且-253使用整数乘以二的幂来表示可表示的数字,而不是更常见的分数有效位,可以简化一些数论和其他关于浮点属性的推理。我在这个答案中使用了它,因为它可以简洁地表示可表示的值集。所以如果我正确的话,我可以使用任何数字
X/Y
,只要Y
是2的幂,并且X
是小于2^53
?@神秘:+1作为答案,但我有一个疑问。24/48=0.5,但是根据上述规则,它不应该是可表示的,因为3是48的主要因素之一,而不是10的主要因素之一。为什么?@legends2k24/48是可约化的。在尝试应用上述规则之前,你应该减少分数。@NiettheDarkAbsol:Aah,明白了,数字应该是互质整数[gcd(X,Y)=1],规则才能起作用。(我想你的意思是1.m*2^e
)这不应该是1.1000000*2^-4
?看,这正是那种“牵涉太深”吗我在我的问题中提到…@Kolink:答案本身就是一个句子,只使用熟悉的整数、乘法、幂和小于(或等于)的概念,精确地说明哪些数字可以表示,哪些数字不能表示。你能得到比这简单多少的答案?你有一个整数乘以的幂