admin管理员组文章数量:1026989
超大浮点数+超小浮点数解析
搜遍全网都是用两个小浮点数加法来解释,且不是按32位总长度来表示,各种原反补码绕来绕去,冗长聒噪,因此决定另辟蹊径讲解:
感性认识:超大浮点数加超小浮点数常常会丢失超小浮点数,也就是加不进去,下面谈下我的理解。
单精度浮点数float有32位,第1位是符号位(0表示此浮点数是正数,1表示此浮点数是负数),接着8位是指数位,范围为0~255,其中0和255是特殊情况:
1、指数为0时,规定其真正指数值大小为1-127即-126,且规定此时尾数开头隐含的那1位值是0,因此尾数范围下限是:
0.0000 0000 0000 0000 0000 000(23位全是0,当然值就是0)
尾数范围的上限是:
0.1111 1111 1111 1111 1111 111(23位全是1,值为1减2的负23次方,即0.99987792964)
综上此时浮点数值非负的范围下限是0,上限是0.99987792964*2^-126可写为[0,1)*2^-126,负数部分范围同理,提示这只是范围,不表示可以取到这个范围中的任何值,只能有选择的表示,能精确表示的是那些可以分解为多个2^n之和的数。
2、指数为255时,又规定了两种情况:当尾数小数部分全为0是,表示±∞;若尾数小数部分不全为0,这表示不是一个数
3、指数为1~254时,规定减去127得到-126~127为实际指数值,而此时尾数范围下限是:
1.0000 0000 0000 0000 0000 000(23位全是0,加上首位1,当然值就是1)
尾数范围的上限是:
1.1111 1111 1111 1111 1111 111(24位全是1,值为2减2的负23次方,即1.99987792964)
综上此时浮点数值非负的范围下限是1*2^-126,此下限刚好连接上指数全为0时的上限0.99987792964*2^-126,上限是1.99987792964*2^127趋近于2*2^127,负数部分范围同理,因此浮点数范围是±2^128,也就是±3.40282367E38
试想指数和尾数为这种情况时:
1.1111 1111 1111 1111 1111 111*2^23值为16777215再加1就是16777216即1.0000 0000 0000 0000 0000 000*2^24,在1~16777216范围分辨率是1,因此这个范围内的整数,浮点数都可以精确表示,在16777217~33554432范围内,也就是1.0000 0000 0000 0000 0000 001*2^24到1.0000 0000 0000 0000 0000 000*2^25这个范围内,尾数在小数点后第23位加1,浮点数值就加2,因此分辨率是2,这个范围中的有些数不能精确表示,如16777217、16777219、16777221……等。因为第8位有大小为1的误差,所以第7位可能有误差,但第6位肯定没有误差,所以浮点数有效位数为6到7位。
重点,浮点数相加时,要先进行对阶,指数小的要变成和指数大的一样大,因此小浮点数的尾数要相应右移,移动位数为大小浮点数指数的差值
下面以超大浮点数8589934592.0即1.0000 0000 0000 0000 0000 000*2^33为例,在8589934592.0~17179869184.0范围内,分辨率为2^(33-23)即1024,而512.0即1.0000 0000 0000 0000 0000 000*2^9
下面当8589934592.0+512.0时有:
1.0000 0000 0000 0000 0000 000*2^33
1.0000 0000 0000 0000 0000 000*2^9
对阶时有:
1.0000 0000 0000 0000 0000 000*2^33
0.0000 0000 0000 0000 0000 0001*2^33
然后相加,相加时要包含移出的位,有:
1.0000 0000 0000 0000 0000 0001*2^33
此时尾数小数部分有24位,多了1位,该位要舍去,但不是简单的舍去:舍去部分的值若超过此时第23位权的一半就在第23加1,否则不加,这里我们第23位的权为2^(33-23)即1024,舍去值为512,未超过1024的一半,因此直接舍去,结果就是8589934592.0+512.0结果还是8589934592.0
思考一下,8589934592.0最少加多少会变成8589935616.0?
由上面的结论可知,只要超过512.0就会加1024.0,那单精度浮点数在512.0之后能精确表示的第一个浮点数是什么?
当然是:
1.0000 0000 0000 0000 0000 001*2^9
即512.00006103516
所以8589934592.0+512.00006103516=8589935616.0
你以为就这样?
由于在大于512.0小于1024.0这个区间,单精度浮点数的分辨率为2^(9-23)=0.00006103516,因此在大于512.0小于512.00006103516范围内的数浮点数都是都无法表示的,这就是表示误差,当向编译器输入值为大于512.0等于512.00003051758时会存储为512.0,而输入大于512.00003051758小于等于512.00006103516时就存储为512.00006103516
因为IEEE754浮点数对于无法精确表示的浮点数默认采用的是向偶舍入,即4舍6入5取偶,但对于浮点数而言,什么是奇?什么是偶呢?规定如下:将浮点数化为IEEE754格式后,其尾数中,小数点右侧第23位,即最后一位为1就是奇,为0就是偶,显然512.00003051758的IEEE754格式为1.0000 0000 0000 0000 0000 0001*2^9,第23位为0是偶,所以第24位直接舍去,整体值为1.0000 0000 0000 0000 0000 000*2^9,也就是512.0;
所以在编译器中对单精度浮点数输入:
8589934592.0+512.00003051759时编译器进行的是:
8589934592.0+512.00006103516
经过舍入得到的是8589934592.0+1024.0=8589935616.0
以上就是我肤浅的理解,如有不当之处,欢迎指正😃
超大浮点数+超小浮点数解析
搜遍全网都是用两个小浮点数加法来解释,且不是按32位总长度来表示,各种原反补码绕来绕去,冗长聒噪,因此决定另辟蹊径讲解:
感性认识:超大浮点数加超小浮点数常常会丢失超小浮点数,也就是加不进去,下面谈下我的理解。
单精度浮点数float有32位,第1位是符号位(0表示此浮点数是正数,1表示此浮点数是负数),接着8位是指数位,范围为0~255,其中0和255是特殊情况:
1、指数为0时,规定其真正指数值大小为1-127即-126,且规定此时尾数开头隐含的那1位值是0,因此尾数范围下限是:
0.0000 0000 0000 0000 0000 000(23位全是0,当然值就是0)
尾数范围的上限是:
0.1111 1111 1111 1111 1111 111(23位全是1,值为1减2的负23次方,即0.99987792964)
综上此时浮点数值非负的范围下限是0,上限是0.99987792964*2^-126可写为[0,1)*2^-126,负数部分范围同理,提示这只是范围,不表示可以取到这个范围中的任何值,只能有选择的表示,能精确表示的是那些可以分解为多个2^n之和的数。
2、指数为255时,又规定了两种情况:当尾数小数部分全为0是,表示±∞;若尾数小数部分不全为0,这表示不是一个数
3、指数为1~254时,规定减去127得到-126~127为实际指数值,而此时尾数范围下限是:
1.0000 0000 0000 0000 0000 000(23位全是0,加上首位1,当然值就是1)
尾数范围的上限是:
1.1111 1111 1111 1111 1111 111(24位全是1,值为2减2的负23次方,即1.99987792964)
综上此时浮点数值非负的范围下限是1*2^-126,此下限刚好连接上指数全为0时的上限0.99987792964*2^-126,上限是1.99987792964*2^127趋近于2*2^127,负数部分范围同理,因此浮点数范围是±2^128,也就是±3.40282367E38
试想指数和尾数为这种情况时:
1.1111 1111 1111 1111 1111 111*2^23值为16777215再加1就是16777216即1.0000 0000 0000 0000 0000 000*2^24,在1~16777216范围分辨率是1,因此这个范围内的整数,浮点数都可以精确表示,在16777217~33554432范围内,也就是1.0000 0000 0000 0000 0000 001*2^24到1.0000 0000 0000 0000 0000 000*2^25这个范围内,尾数在小数点后第23位加1,浮点数值就加2,因此分辨率是2,这个范围中的有些数不能精确表示,如16777217、16777219、16777221……等。因为第8位有大小为1的误差,所以第7位可能有误差,但第6位肯定没有误差,所以浮点数有效位数为6到7位。
重点,浮点数相加时,要先进行对阶,指数小的要变成和指数大的一样大,因此小浮点数的尾数要相应右移,移动位数为大小浮点数指数的差值
下面以超大浮点数8589934592.0即1.0000 0000 0000 0000 0000 000*2^33为例,在8589934592.0~17179869184.0范围内,分辨率为2^(33-23)即1024,而512.0即1.0000 0000 0000 0000 0000 000*2^9
下面当8589934592.0+512.0时有:
1.0000 0000 0000 0000 0000 000*2^33
1.0000 0000 0000 0000 0000 000*2^9
对阶时有:
1.0000 0000 0000 0000 0000 000*2^33
0.0000 0000 0000 0000 0000 0001*2^33
然后相加,相加时要包含移出的位,有:
1.0000 0000 0000 0000 0000 0001*2^33
此时尾数小数部分有24位,多了1位,该位要舍去,但不是简单的舍去:舍去部分的值若超过此时第23位权的一半就在第23加1,否则不加,这里我们第23位的权为2^(33-23)即1024,舍去值为512,未超过1024的一半,因此直接舍去,结果就是8589934592.0+512.0结果还是8589934592.0
思考一下,8589934592.0最少加多少会变成8589935616.0?
由上面的结论可知,只要超过512.0就会加1024.0,那单精度浮点数在512.0之后能精确表示的第一个浮点数是什么?
当然是:
1.0000 0000 0000 0000 0000 001*2^9
即512.00006103516
所以8589934592.0+512.00006103516=8589935616.0
你以为就这样?
由于在大于512.0小于1024.0这个区间,单精度浮点数的分辨率为2^(9-23)=0.00006103516,因此在大于512.0小于512.00006103516范围内的数浮点数都是都无法表示的,这就是表示误差,当向编译器输入值为大于512.0等于512.00003051758时会存储为512.0,而输入大于512.00003051758小于等于512.00006103516时就存储为512.00006103516
因为IEEE754浮点数对于无法精确表示的浮点数默认采用的是向偶舍入,即4舍6入5取偶,但对于浮点数而言,什么是奇?什么是偶呢?规定如下:将浮点数化为IEEE754格式后,其尾数中,小数点右侧第23位,即最后一位为1就是奇,为0就是偶,显然512.00003051758的IEEE754格式为1.0000 0000 0000 0000 0000 0001*2^9,第23位为0是偶,所以第24位直接舍去,整体值为1.0000 0000 0000 0000 0000 000*2^9,也就是512.0;
所以在编译器中对单精度浮点数输入:
8589934592.0+512.00003051759时编译器进行的是:
8589934592.0+512.00006103516
经过舍入得到的是8589934592.0+1024.0=8589935616.0
以上就是我肤浅的理解,如有不当之处,欢迎指正😃
本文标签: 超大浮点数+超小浮点数解析
版权声明:本文标题:超大浮点数+超小浮点数解析 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://it.en369.cn/IT/1694668990a254844.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论