关于小数0.0/0.0问题

关于小数0.0/0.0问题
首先我们了解一下小数在计算机是如何存储的,对于整数而言,情况比较简单,直接连续除以2取余。得到二进制整数的表达方式,而真正的难点就是小数如何转化二进制码。(注意小数和浮点数)
十进制的小数可以转化为二进制小数(整数部分连续除以二,小时部分连续乘2),但计算机根本不懂小数点,那应该怎末处理呢?
表达浮点数的0,1序列被分为三部分,以32位单精度浮点数为例,其具体的转换规则是:首先把二进制小数(补码)用二进制科学计数法表示,比如例子1111101.001=1.111101001*26。符号位sign表示数的正负(0为正,1为负),故此处填0。exponent表示科学计数法的指数部分,请务必注意的是,这里所填的指数并不是前面算出来的实际指数,而是等于实际指数加上一个数(指数偏移),偏移量为2(e-1)-1,其中e是exponent的宽度(位数)。对于32位单精度浮点数,exponent宽度为8,因此偏移量为127,所以exponent的值为133,即10000101。之后的fraction表示尾数,即科学计数法中的小数部分11110100100000000000000(共23位)。因此32位浮点数125.125D在计算机中就被表示为01000010111110100100000000000000。
在这里插入图片描述

对于32位单精度浮点数,sign是1位,exponent是8位(指数偏移量是127),fraction是23位。对于64位双精度浮点数,sign是1为,exponent是11位(指数偏移量是1023),fraction是52位。
即使在精度相同的情况下,比较也可能会出问题。因为在运算过程中会将内存(或高速缓存)中的值加载到CPU浮点寄存器(80 bit扩展精度)中,然后再进入CPU浮点计算单元进行计算,计算结果写回浮点寄存器,然后写回内存(或高速缓存)。从内存到浮点寄存器,浮点数的精度会扩展,从浮点寄存器到内存,浮点数的精度会降低(精度扩展通常没问题,但如果精度降低了,很可能值会发生变化,出现截断),而浮点运算的结果由于下面还要使用所以暂时保存在浮点寄存器中留待下次使用(没有及时写回内存,这是一种优化策略),从而导致数据并不是内存中和内存中的数据比较而是浮点寄存器中的值和内存中的值进行比较,而无论内存中是float类型还是double类型,其精度和浮点寄存器精度都不相同,从而导致比较结果是不相等。
在这里插入图片描述
另外值得注意的是Java中整数除以0会报出异常,如果是浮点型则会出现正无穷或者负无穷,0.0除以0的时候或出现NaN。

NaN与任何值都不相等,包括与自己都不相等。

作者:十九岁的me
来源:CSDN
原文:https://blog.csdn.net/qq_43467548/article/details/90781057
版权声明:本文为博主原创文章,转载请附上博文链接!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值