C#浮点数的表示和基本运算

2019-12-30 14:40:36刘景俊

再回来看指数,根据前面的定义,P-127=16,那么P = 143,表示成二进制就是:10001111。

45678.0f这个数是正的,所以符号位是0,那么我们按照前面讲的格式把它拼起来,就是:0 10001111 10110010011011100000000。

这就是45678.0f这个数的二进制表示,如果我们要得到16进制的表示,非常简单,我们只需要把这个二进制串4个一组,转换成16进制数就可以了。但是要注意的是x86架构的CPU都是Little Endian的(也就是低位字节在前,高位字节在后),所以在实际内存中该数字是按上面二进制串的倒序存储的。要知道CPU是不是little endian的也很容易。

BitConverter.IsLittleEndian;

4.2 含小数的浮点数表示为二进制

对于含小数的浮点数,会有精度的问题,下面举例说明。假设要转换的小数为123.456f。

对于这种带小数的就需要把整数部和小数部分开处理。对于整数部分的处理不再赘述,直接化成二进制为:100100011。小数部份的处理比较麻烦一些,我们知道,使用二进制表示只有0和1,那么对于小数就只能用下面的方式来表示:

a1*2-1+a2*2-2+a3*2-3+......+an*2-n

其中a1等数可以是0或者1,从理论上将,使用这种表示方法可以表示一个有限的小数。但是尾数只能有23位,那么就必然会带来精度的问题。

在很多情况下,我们只能近似地表示小数。来看0.456这个十进制纯小数,该如何表示成二进制呢?一般说来,我们可以通过乘以2的方法来表示。

首先,把这个数字乘以2,小于1,所以第一位为0,然后再乘以2,大于1,所以第二位为1,将这个数字减去1,再乘以2,这样循环下去,直到这个数字等于0为止。

在很多情况下,我们得到的二进制数字都大于23位,多于23位的就要舍去。舍入原则是0舍1入。通过这样的办法,我们可以得到二进制表示:1111011.01110100101111001。

现在开始向左移小数点,一共移了6位,这时候尾数为:1.11101101110100101111001,阶码为6加上127得131,二进制表示为:10000101,那么总的二进制表示为:

0  10000101  11101101110100101111001

表示成十六进制是:42  F6  E9  79

由于CPU是Little Endian的,所以在内存中表示为:79  E9  F6  42。

4.3 将纯小数表示成二进制

对于纯小数转化为二进制来说,必须先进行规格化。例如0.0456,我们需要把它规格化,变为1.xxxx * (2n )的形式,要求得纯小数X对应的n可用下面的公式:
n = int( 1 + log 2X )

0.0456我们可以表示为1.4592乘以以2为底的-5次方的幂,即1.4592 * ( 2-5 )。转化为这样形式后,再按照上面处理小数的方法处理,得到二进制表示

1. 01110101100011100010001