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

时间:2017-05-10 00:06:06

标签: assembly x86 denormalized

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

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

符号位和指数= 0.

所以我有:

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

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

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

注意:我需要能够为我的决赛手动执行此操作。

2 个答案:

答案 0 :(得分:2)

对half,float或double的尾数(OP?位)进行归一化以去除前导零。通常这样做直到数量为1.0 <=数量<1。 2.0。但在这种情况下,数字在子法线范围内(指数是00000,因为你已经建立。这意味着原始数字小于最小法线6.10352×10 ^ -5,即当你尝试移动到数字1.0 <=数字&lt; 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)

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

sign   exp      mantissa
0      00000    1011000011

可以使用numpy和struct

使用python检查
>>> 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代码。这可能对学习有用。

答案 1 :(得分:0)

所以代替你的号码将手工转换为0.2十进制到二进制。

从一个程序开始,给我一些基础10的分数,可能是一个更好的方法来做到这一点,我发送的链接不适用于整数。

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,所以假设采用舍入舍入模式,它不会向上舍入...

这是16位IEEE浮点格式的0.2的标准化版本。

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

Emin = 000012 − 011112 = −14

因此,如果您必须移动超过14位,则无法将此数字标准化,那么14的N是最糟糕的情况。所以他们在维基百科中有一个这样的案例,他们称之为与非正规相同的次正常。你将它向左移动了14位,这是由2 ^ -14暗示的,所以你将二进制数转换为0.xxxxxxxxxx * 2 ^ -14,无论前十个xxxxx位是你的尾数/分数。并且编码中的指数是特殊数字00000

所以0 00000 xxxxxxxxxx是IEEE 754半点二进制文件中非常规的编码。