我正在尝试将 0.0000211 转换为二进制。到目前为止,这是我的理解:
E = -bias + 1. 偏差 = 15, E = -14
符号位和指数 = 0。
所以我有:
0 00000 ????????????
半点格式为 1 个符号位、5 个指数位和 10 个小数位。
我的问题是如何找到这个非规范化数字的分数?E 和偏差在这种情况下意味着什么?任何帮助,将不胜感激
注意:我需要能够为我的期末考试手动执行此操作。
我正在尝试将 0.0000211 转换为二进制。到目前为止,这是我的理解:
E = -bias + 1. 偏差 = 15, E = -14
符号位和指数 = 0。
所以我有:
0 00000 ????????????
半点格式为 1 个符号位、5 个指数位和 10 个小数位。
我的问题是如何找到这个非规范化数字的分数?E 和偏差在这种情况下意味着什么?任何帮助,将不胜感激
注意:我需要能够为我的期末考试手动执行此操作。
half、float 或 double 的尾数(OPs ? bits)被标准化以去除前导零。通常这样做直到数字为 1.0 <= number < 2.0。但在这种情况下,数字在亚法线范围内(指数为 00000,正如您已经确定的那样。这意味着原始数字小于 6.10352 × 10^-5 的最小法线,即当您尝试时要移动以使数字 1.0 <= number < 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 ? 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 的小数转换为二进制,并记住一些规则。你似乎在计算指数之上。
看一下...
这个问题的答案之一是用于整个转换的 python 代码。这可能对学习有用。
因此,您的数字不会手动将 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。
所以半点格式似乎是
看到eeemmmmmmmm
并且偏差是 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,无论前十个 xxxxxx 位是尾数/分数。并且编码中的指数是一个特殊的数字 00000
所以 0 00000 xxxxxxxxxx 是 IEEE 754 半点二进制中非正规的编码。