IEEE 754 非规范化十进制转换为半点二进制

IEEE 754 Denormalized Decimal Converting to Half-Point Binary

我正在尝试将 0.0000211 转换为二进制。这是我目前的理解:

E = -bias + 1.bias = 15, E = -14

符号位和指数 = 0。

所以我有:

0 00000 ??????????

半点格式为1个符号位,5个指数位,10个小数位。

我的问题是如何找到这个非规范化数字的分数?在这种情况下,E 和偏差是什么意思?任何帮助将不胜感激

注意:我需要能够为我的期末考试手动执行此操作。

half、float 或 double 的尾数(OPs ? 位)被归一化以删除前导零。通常这样做直到数字为 1.0 <= number < 2.0。但在这种情况下,数字在次正常范围内(指数为 00000,正如您已经确定的那样。这意味着原始数字小于 6.10352 × 10^−5 的最小正常值,即当您尝试时移动使数字 1.0 <= 数字 < 2.0,你达到了指数的最小限制),在这种情况下,它们移动了 15 次,即乘以 2^15 并在点后存储尽可能多的位(对于半浮点此是 10 位)。这样做意味着它们可以存储非常小的数字,因为对于次正常范围,它们在恢复数字时在尾数前面有一个隐含的 0. 并且它们允许尾数上有前导零。

所以 0.0000211 = b'0.000000000000000101100001111111111100111...

2^15 * 0.0000211 = 0.6914048 = b'0.101100001111111111100111...

我们存储 1011000011,因为次正常范围删除了隐含的 0。(即对于 0.XXXXXXXXXX 我们只存储 Xs)

所以在这种情况下,尾数(OP?位)是 1011000011

sign   exp      mantissa
0      00000    1011000011

这可以通过 python 使用 numpy 和 struct

检查
>>> import numpy as np
>>> import struct
>>> a=struct.pack("H",int("0000001101010000",2))
>>> np.frombuffer(a, dtype =np.float16)[0]
2.116e-05

那么对于你的最后... 至少您需要学习如何将小于 1.0 的小数转换为二进制,并记住一些规则。您似乎在计算指数。

看看...

https://math.stackexchange.com/questions/1128204/how-to-convert-from-floating-point-binary-to-decimal-in-half-precision16-bits

这个问题的答案之一有整个转换的 python 代码。可能对学习有用。

因此,您的数字不会手动将 0.2 十进制转换为二进制。

从一个程序开始,给我一些以 10 为基数的分数,这可能是一个更好的方法,我发送的 link 不适用于整数。

1/2 0.50000000
1/4 0.25000000
1/8 0.12500000
1/16 0.06250000
1/32 0.03125000
1/64 0.01562500
1/128 0.00781250
1/256 0.00390625

所以:

0.2 - 0.5 no 
0.2 - 0.25 no
0.2 - 0.125 = 0.075
0.075 - 0.0625 = 0.0125
0.0125 - 0.03125 no
0.0125 - 0.015625 no
0.0125 - 0.00781250 = 0.0046875
0.0046875 - 0.00390625 = 0.00078125
0.00078125 - 0.001953125 no
0.00078125 - 0.0009765625 no
0.00078125 - 0.00048828125 yes

我碰巧知道这不能用二进制表示,它是 重复数字所以上面告诉我:

0.0011001100110011...

是以 10 为基数的 0.2 的二进制数。

现在为了规范化我需要 1.xxxx 所以我左移 3 得到

1.1001100110011 * 2^(-3)

IEEE 754 单精度格式(尾数和分数是一回事)

seeeeeeeemmmmmmmmmmmmmmmmmmmmmmm

正数所以符号 s 为零

指数是 2 的 e-127 次方

所以我们将 127 偏差添加到 -3 得到 124 0x7c

请注意,由于 1.xxxx 暗示没有理由浪费被删除的 1,我们只是将分数放入。

0 01111100 10011001100110011001100
0011 1110 0100 1100 1100 1100 1100 1100
0x3E4CCCCC

现在我作弊,让电脑帮我转换,得到:

0 01111100 10011001100110011001101
0x3E4CCCCD

这是有道理的,因为在我们砍掉末端之前,我们有 11001,最后被砍掉的位大于或等于我们基数的一半,所以如果我们想四舍五入,我们就四舍五入,使它成为 1101。当我们以十为基数进行四舍五入,我们需要等于或一半的基数,所以 5 0.105 四舍五入为 0.11。所以二进制 0.11001 四舍五入为 0.1101.

所以半点格式似乎是

seeeeemmmmmmmmmm

偏差为 2^(e-15)

所以我们将 15 加到 -3 上得到 12

s 是 0 它是正数 e 是 12 并且我假设 m 没有隐含的 1 位 所以

0 01100 1001100110
0011 0010 0110 0110
0x3266

它被截断的地方是 0,因此假设采用舍入模式,它不会舍入...

所以这是 0.2 的标准化版本,采用 16 位 IEEE 浮点格式。

现在,如果您阅读维基百科,它足以理解这一点,如果 当您将其标准化为 1.xxxxx 时,您将向左移动(如果大于 [=66= 则向右移动,如果小于 1.xxxx 则向左移动,在这种情况下)一些数字 N 位来做到这一点所以你的数字是 1.xxxx 乘以 2^(-N),如维基百科页面

所示
Emin = 000012 − 011112 = −14

所以 N 为 14 是最坏的情况,如果你必须移动超过 14 位,你就不能标准化这个数字。所以他们在维基百科中有一个案例,他们称其为次正规的,与非正规的相同。你将它向左移动 14 位,这由 2^-14 暗示,所以你将你的二进制数转换为 0.xxxxxxxxxx * 2^-14,无论前十个 xxxxx 位是你的 mantissa/fraction。并且编码中的指数是一个特殊的数字 00000

so 0 00000 xxxxxxxxxx 是 IEEE 754 半点二进制的非正规编码。