发布网友 发布时间:2022-05-06 13:44
共3个回答
热心网友 时间:2022-06-30 19:35
这个牵涉到浮点数在计算机中的表示。计算机中数字是以0和1二进制保存的,我们熟悉的是整数的如何在计算机中表示,那么浮点数是如何表示的呢?
一. 转换
我们先来看看如何将十进制的浮点数转换成二进制。
一个十进制的浮点数,例如:abcd.efg (其中a~g为0..9),其值用多项式为:
a*10^3 + b*10^2 + c*10^1+d*10^0+e*10^(-1)+f*10^(-1)+g*10^(-3)。
而一个二进制的浮点数,我们也将其表示成:abcd.efg (其中a~g为0或1),其值表示为:
a*2^3 + b*2^2 + c*2^1+d*2^0+e*2^(-1)+f*2^(-1)+g*2^(-3)。
我们看到底由十进制时的10换成了二进制时的2了,其它都一样。所以一个十进制的浮点数转换成二进制必须分两步进行:整数部分和小数部分。
1. 对于整数部分,和以前的整数转换是一样的。
2. 对于小数部分,比较特殊。下面讲两种转换方法。
方法一:依次与2^(-n)作比较(n从1开始),若大于该值则为1,且减去此值,否则为0;然后继续下一轮比较。举例说明:将0.842356转换成二进制:
此时,你会发现比较将会是无穷无尽的。如果你截取到某位,必须做一些取舍。取舍的标准是:其后一位若为1则进1;后一位为0则不进。
还是以上面为例,若要截取9位,因为第10位为0,故不进位,则最终的结果为:0.110101111
;若要截取到8位,因为第9位为1,故要进位,则最终的结果为:0.110110000
(即0.1101101111 + 0.0000000001)。从这个例子可以看出十进制小数的转换成二进制时只是一个近似值。其实大部分浮点数保存在计算机中都只是一个近似值。至于是稍微大于原值还是稍微小于原值,要看截取时有无进位。
方法二:若在计算机中计算方法一的过程,因为2^(-n)本身就是一个浮点数,而浮点数之间的比较和计算难免有误差。所以我想到了下面这个方法:
1) 首先生成首数字为1、后面0的个数为小数位数的基准数,比如0.254的基准数为1000、0.00353的基准数为100000。
2) 将小数部分乘以上面的基准数,这样得到一个整数。
3) 对该整数乘以2,若积大于基准数,则为1,同时将积减去基准数后得新的整数;若积小于基准数,则为0。
4) 用新的整数重复步骤3,直到整数为0或者到需要的精确位数,作取舍后结束。
举例说明:将0.842356转换成二进制,基准数为1000000,转换成整数为842356,
此法可以有效地避免浮点数的比较,能方便且快捷地获得对应的二进制值。
二. 存储
现在已转换成浮点二进制了,那么如何在计算机中表示呢?这要说到科学计数法,这个大家比较熟悉。十进制的科学计算法可以表示成如下:(-1)^s * M * 10^E
,S表示符号:S为1表示负数;0为正数。M成为尾数,其范围为1<=M <10 。E被成为幂,也叫指数。
二进制的科学计数法,也是IEEE的浮点数标准格式,和十进制格式一样:(-1)^s * M * 2^E
。M的范围1<= M <2。将一个二进制浮点数转换成科学计算法很简单,例如:
1)10001.110001 小数点左移4位后成 (-1)^0 * (1.0001110001) * 2 ^ 4.
2) -0.000010001 小数点右移4位后成(-1)^1 * (1.0001) * 2 ^ ( – 4)
在计算机中,表示浮点数由两种常用的格式:单精度浮点数和双精度浮点数,它们在精度上有所差别,同时所需要的空间也有差别:
1) 当为负数时,符号位为1,否则为0。
2) 指数有正数亦有负数,这里保存时使用了加偏移量的方法:8位指数位的指数范围为-127~128,其偏移量为127;11位指数范围为-1023~1024,其偏移量为1023。保存时指数加上偏移量,可以避免负数问题;取值时再减去偏移量就行了。
3) 因为尾数1<=M<2,就是说小数点前面总是有一个1。为了节省空间,将此处的1省去,直接将小数点后面的部分放入到小数部分(这也是这部分为什么叫“小数部分”,而不是“尾数部分”的原因)。
举一例:将12.842356保存成单精度浮点格式。
1) 首先将它转换成二进制格式:1100.11010111101001001010,后面位直接截去。
2) 转换成科学计数法格式:1. 10011010111101001001010。右移3位于是指数为3+127=130,二进制为10000010。
3)
于是符号位为0,指数为:10000010,小数去掉前面的1后为10011010111101001001010。这些二进制就是最终保存在电脑里的格
式:0 10000010 10011010111101001001010,十六进制格式为:0x414D7A4A。
热心网友 时间:2022-06-30 19:35
小数是以二进制存储的,也就是说小数是通过2(负1次方)+2(负2次方)+2(负3次方)+。。。。+2(负N次方)N越大越精确热心网友 时间:2022-06-30 19:36
在计算机里,float是用2进制浮点数表示的,10进制的123.456转换成2进制,就有了误差,再转回来,就看到这个误差了。