如何用C表示内存中的FLOAT编号

Ami*_*mar 39 c floating-point

在阅读教程时,我遇到了如何在内存中表示浮点数.本教程有一个带浮点数的例子.

   float a=5.2  with below Diagram
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

任何人都可以告诉我5.2如何转换为二进制文件以及它如何在上图中的内存中表示?

Rud*_*uis 51

如上所述,5.2表示为符号位,指数和尾数.你怎么编码5.2?

5很容易:

101. 
Run Code Online (Sandbox Code Playgroud)

剩下的,0.2是1/5,所以将1.00000...(十六进制)除以5得到0.3333333...(十六进制).

(如果考虑少一点,可以更容易地遵循:0.FFFF...F / 5 = 3,因此很容易看出0.FFFF... / 5 = 0.33333....当除以5时,一个缺失位并不重要,所以1.0000... / 5 = 0.3333...也是如此).

那应该给你

0.0011001100110011001100110011... 
Run Code Online (Sandbox Code Playgroud)

加5,你得到

101.00110011001100110011...         exp 0    (== 5.2 * 2^0)
Run Code Online (Sandbox Code Playgroud)

现在向右移动(将其标准化,即确保顶部位在小数点之前)并相应地调整指数:

1.010011001100110011001100110011... exp +2   (== 1.3 * 2^2 == 5.2)
Run Code Online (Sandbox Code Playgroud)

现在你只需要向129 = 0b10000001指数添加127(即)的偏差并存储它:

0 10000001 1010 0110 0110 0110 0110 0110 
Run Code Online (Sandbox Code Playgroud)

忘记尾数的前1(除了一些特殊的值,它总是应该是1,所以它不存储),你得到:

01000000 10100110 01100110 01100110
Run Code Online (Sandbox Code Playgroud)

现在你只需要决定小端或大端.

这不完全是它的工作原理,但是当5.2之类的数字转换为二进制时,或多或少会发生这种情况.

  • 指数计算2的幂.该数字不应改变其值,因此如果将尾数右移一位(相当于除以2),则指数必须加1(相当于乘以2).对于5.2,你这样做了两次.最高位必须始终为1,"十进制/二进制点"就在它后面.所以你从5.2*2 ^ 0到2.6*2 ^ 1到1.3*2 ^ 2.该值必须始终在1和2之间(特殊值除外,如0或**非常小的值,或NaN等).这称为标准化.由于顶部位始终为1,因此不会存储它. (5认同)
  • 指数已完成“移位”,因此您可以存储小于零的指数。例如0.125为1/8。存储为尾数(1)00 ...,符号+,Exp 124(127-3) (2认同)

phi*_*mue 48

我认为图表不是一个正确的百分比.

浮点数存储在内存中,如下所示:

它们被分解为:

  • 符号s(表示它是正还是负) - 1位
  • 尾数m(基本上是你的数字的数字 - 24位
  • 指数e- 7位

然后,您可以将任何数字写xs * m * 2^ewhere ^表示取幂.

5.2应表示如下:

0 10000001 01001100110011001100110    
S    E               M
Run Code Online (Sandbox Code Playgroud)

S=0 表示它是正数,即 s=+1

E将被解释为无符号数,从而表示129.请注意,您必须从中减去127 E以获得原始指数e = E - 127 = 2

M必须按以下方式解释:它被解释为以a开头,1后跟一个point(.),然后是该点之后的数字.后面的数字.是实际编码的数字m.我们为每个数字引入权重:

bits in M: 0   1    0     0      1       ... 
weight:    0.5 0.25 0.125 0.0625 0.03125 ... (take the half of the previous in each step)
Run Code Online (Sandbox Code Playgroud)

现在总结相应位设置的权重.完成此操作后,添加1(由于IEEE标准中的规范化,您总是为解释添加1 M)并获取原始数据m.

现在,您计算x = s * m * 2^e并获取原始数字.

因此,唯一剩下的就是在实际内存中,字节可能是相反的顺序.这就是为什么数字可能不会存储如下:

0 10000001 01001100110011001100110    
S    E               M
Run Code Online (Sandbox Code Playgroud)

但更多的是相反(简单地采取8位块并镜像他们的顺序)

01100110 01100110 10100110 01000000
MMMMMMMM MMMMMMMM EMMMMMMM SEEEEEEE
Run Code Online (Sandbox Code Playgroud)

  • IEEE-754中的浮点数用8位指数和23位尾数表示.这排除了隐藏位,它始终为1(除了非正规或NaN或0),因此尾数(有效数字)通常为24位,但只存储23位.显示的图表对于小端浮标几乎是正确的.M应该始终具有1的最高位,并且相应地调整指数. (4认同)

小智 7

该值以相反的顺序表示在存储器中,但由于浮点值的准确性损失,混淆点可能是5.2f实际上表示为5.1999998.


vij*_*231 5

用二进制逻辑表示5.2很简单:

     8 4 2 1
5 -> 0 1 0 1
Run Code Online (Sandbox Code Playgroud)

对于十进制数:

取 0.2 并乘以 2(因为它以二进制表示)。

.2 X 2 = 0.4 -> take the value after the
                decimal point, don't take the value before
                the decimal point

.4 X 2 = 0.8
.8 X 2 = 1.6
.6 X 2 = 1.2
.2 X 2 = 0.4
Run Code Online (Sandbox Code Playgroud)

等等...

在此步骤之后,从上述步骤的输出中取出小数点前的值:

.2 X 2 = 0.4 -> take 0 from this for representing in binary form
Run Code Online (Sandbox Code Playgroud)

所以 5.2 的最终 o/p 是:

0101.00110...
Run Code Online (Sandbox Code Playgroud)

  • 这不是浮点表示,只是普通的二进制表示。 (4认同)