【问题标题】:IEEE 754 Denormalized Decimal Converting to Half-Point BinaryIEEE 754 非规格化十进制转换为半点二进制
【发布时间】:2017-10-08 11:07:08
【问题描述】:

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

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

符号位和指数 = 0。

所以我有:

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

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

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

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

【问题讨论】:

  • 我可以在十六进制/二进制/十进制之间进行转换,但我在处理非规范化数字时遇到了问题。您是说它与链接中描述的方法相同吗?感谢您的评论
  • 非正规是什么意思?意味着您无法将数字标准化为指定的格式,该数字非常小,以至于当您移动小数点(调整指数)时,您在数字为 +/-1.xxxxx 二进制形式之前达到了指数限制(对于IEEE754)。
  • 所以您需要做的第一件事就是将其从十进制转换为二进制,然后尝试将其转换为任何编码,不确定如何在不先将其转换为二进制的情况下从十进制转换为编码无论如何。
  • 如果我想将 1234 十进制转换为一个字节,我会先将其转换为 0x4D2 然后决定它是否适合一个字节......(当然在这种情况下我可以采取捷径是它更大超过 256)

标签: assembly x86 denormalized


【解决方案1】:

half、float 或 double 的尾数(OPs ? bits)被标准化以去除前导零。通常这样做直到数字为 1.0

所以 0.0000211 = b'0.000000000000000101100001111111111100111...

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

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

所以在这种情况下,尾数(OPs ? bits)是 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 代码。这可能对学习有用。

【讨论】:

    【解决方案2】:

    所以不是你的数字会手动将 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。

    所以半点格式似乎是

    见eeemmmmmmmmmm

    偏差为 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 时,您将向左移动(如果大于 1.xxxx 则向右移动,如果小于 1.xxxx 则向左移动,在这种情况下)一些 N 位来执行此操作,因此您的数字为 1.xxxx如维基百科页面所示,乘以 2^(-N)

    Emin = 000012 − 011112 = −14
    

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

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

    【讨论】:

    • duh, 2^16 * 0.2 = 13107.2 = 0x3333 右移 16 是 0.001100110011 这就是快捷方式,谢谢 Clayton...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-02
    • 1970-01-01
    • 2016-01-31
    • 1970-01-01
    • 2013-10-04
    • 2019-12-13
    相关资源
    最近更新 更多