如何在浮点运算和十进制中表示0.1

Jac*_*ada 11 c# floating-point double decimal bit-representation

我试图更好地理解浮点运算,并且已经看到了"每个计算机科学家应该知道浮点算术的内容"的一些链接.

我还是不明白,一些怎么样0.10.5存储在花车和小数.

有人可以解释它是如何布局的记忆?

我知道浮子是两部分(即一个数字的东西).

pax*_*blo 40

我一直指向人们对Harald Schmidt的在线转换器,以及维基百科IEEE754-1985文章及其漂亮的图片.

对于这两个特定值,您得到(为0.1):

s eeeeeeee mmmmmmmmmmmmmmmmmmmmmmm    1/n
0 01111011 10011001100110011001101
           |  ||  ||  ||  ||  || +- 8388608
           |  ||  ||  ||  ||  |+--- 2097152
           |  ||  ||  ||  ||  +---- 1048576
           |  ||  ||  ||  |+-------  131072
           |  ||  ||  ||  +--------   65536
           |  ||  ||  |+-----------    8192
           |  ||  ||  +------------    4096
           |  ||  |+---------------     512
           |  ||  +----------------     256
           |  |+-------------------      32
           |  +--------------------      16
           +-----------------------       2
Run Code Online (Sandbox Code Playgroud)

标志是积极的,这很容易.

指数是64+32+16+8+2+1 = 123 - 127 bias = -4,所以乘数是或.2-41/16

尾数很粗糙.它由1(隐式基数)加上(对于所有这些位,每个位都值得作为起始位置并且向右增加),.1/(2n)n1{1/2, 1/16, 1/32, 1/256, 1/512, 1/4096, 1/8192, 1/65536, 1/131072, 1/1048576, 1/2097152, 1/8388608}

当你添加所有这些,你得到1.60000002384185791015625.

当你乘以乘数时,你会得到0.100000001490116119384765625,这就是为什么他们说你不能完全代表0.1IEEE754浮点数,并为人们回答"why doesn't 0.1 + 0.1 + 0.1 == 0.3?"类型问题提供了很多机会:-)


0.5示例基本上更容易.它表示为:

s eeeeeeee mmmmmmmmmmmmmmmmmmmmmmm
0 01111110 00000000000000000000000
Run Code Online (Sandbox Code Playgroud)

这意味着它是隐含的基础,1加上没有其他添加剂(所有尾数位都为零).

标志再次是积极的.指数是64+32+16+8+4+2 = 126 - 127 bias = -1.因此,乘数是或.2-11/20.5

所以最终值1乘以0.50.5.瞧!


我有时会发现用十进制更容易想到它.

数字1.345相当于

1 + 3/10   + 4/100 + 5/1000
Run Code Online (Sandbox Code Playgroud)

要么:

        -1       -2      -3
1 + 3*10   + 4*10  + 5*10
Run Code Online (Sandbox Code Playgroud)

同样,小数的IEEE754表示形式为0.8125:

s eeeeeeee mmmmmmmmmmmmmmmmmmmmmmm
0 01111110 10100000000000000000000
Run Code Online (Sandbox Code Playgroud)

隐含的基数为1,相当于二进制:

         01111110-01111111
1.101 * 2
Run Code Online (Sandbox Code Playgroud)

要么:

                     -1
(1   + 1/2 + 1/8) * 2     (no 1/4 since that bit is 0)
Run Code Online (Sandbox Code Playgroud)

变为:

(8/8 + 4/8 + 1/8) * 1/2
Run Code Online (Sandbox Code Playgroud)

随后变为:

13/8 * 1/2 = 0.8125
Run Code Online (Sandbox Code Playgroud)