我试图将int
转换为自定义浮点数,其中用户指定为exp和尾数保留的位数,但我不明白转换的工作原理。我的函数接受一个int值,而int exp表示数字(值* 2 ^ exp),即值= 12,exp = 4,返回192.但我不理解我需要做的更改过程这些。我已经看了好几天并玩IEEE转换器网络应用程序,但我不了解规范化过程是什么。就像我看到它"移动二进制点并调整指数"但是我不知道这意味着什么,能有人给我一个例子吗?另外,我不明白指数偏差是什么。我唯一的信息是你只是给你的指数添加一个数字,但我不明白为什么。我一直在谷歌搜索我能理解的例子,但这对我没有任何意义
答案 0 :(得分:17)
当我们强制其尾数的整数部分正好为1
并允许其分数部分为我们喜欢的任何部分时,浮点数是规范化。
例如,如果我们取二进制13.25
为1101.01
,则1101
为整数部分,01
为分数部分
我可以将13.25
表示为1101.01*(2^0)
,但这不是规范化的,因为整数部分不是1
。 然而,如果我们将指数增加1,我们可以将尾数移到右边的一位数:
1101.01*(2^0)
= 110.101*(2^1)
= 11.0101*(2^2)
= 1.10101*(2^3)
此表示1.10101*(2^3)
是13.25
的标准化形式。
那就是说,我们知道标准化的浮点数总是以1.fffffff * (2^exp)
为了效率,我们不打扰将1
整数部分存储在二进制表示本身中,我们只是假装它在那里。因此,如果我们为尾数提供定制的浮点类型5位,我们就会知道位10100
实际上代表1.10100
。
以下是标准23位尾数的示例:
至于指数偏差,让我们看一下标准的32位float
格式,它分为3个部分:1个符号位,8个指数位和23个尾数位:
s eeeeeeee mmmmmmmmmmmmmmmmmmmmmmm
指数00000000
和11111111
有特殊用途(如代表Inf
和NaN
),因此使用8个指数位,我们可以代表254个不同的指数,比如说{例如,{1}}到2^1
。但是,如果我们想要代表2^254
怎么办?我们如何获得负面指数?
格式通过自动从指数中减去127 来解决此问题。因此:
2^-3
将为0000 0001
1 -127 = -126
将为0010 1101
45 -127 = -82
将为0111 1111
127-127 = 0
将为1001 0010
这会将指数范围从136-127 = 9
更改为2^1 ... 2^254
,因此我们可以代表负指数。
答案 1 :(得分:4)
"规范化过程"将输入转换为选择范围。
binary32期望有效数字(不是尾数)在1.0 <= s < 2.0
范围内,除非该数字具有最小指数。
例:
value = 12, exp = 4
与
相同value = 12/(2*2*2), exp = 4 + 3
value = 1.5, exp = 7
由于有效数字始终具有1
的前导数字(除非该数字具有最小指数),因此无需存储它。而不是将指数存储为7
,而是向其添加127的偏差。
value = 1.5 decimal - &gt; 1.1000 ... 000二进制 - &gt;存储二进制0.1000 ... 000(总共23位)
exp = 7 - &gt; bias exp 7 + 127 - &gt; 134十进制 - &gt; 10000110二进制
存储的二进制模式是&#34;符号&#34;,&#34;有效数字的串联,前导1位隐含&#34;和&#34;偏见指数&#34;
0 10000110 1000...000 (1 + 8 + 23 = 32 bits)
如果偏差指数为0
- 最小值,则隐含位为0
,因此可以存储0.0
这样的小数字。
当偏差指数为255
- 最大值时,存储的数据不再代表有限数,而是&#34;无穷大&#34;和#34;非数字&#34;。
查看引用的链接以获取更多详细信息。
答案 2 :(得分:3)
Tommy - chux和eigenchris以及其他人提供了出色的答案,但如果我正确地看待你的评论,你似乎仍然在努力解决&#34;我将如何?获取此信息,然后在创建自定义浮点表示时使用它,其中用户指定指数的位数?&#34;不要感觉不好,这是你经历过的十几次泥泞。我想我可以尝试清理它。
您熟悉IEEE754-Single-Precision-Floating-Point表示:
IEEE-754 Single Precision Floating Point Representation of (13.25)
0 1 0 0 0 0 0 1 0 1 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -|
|s| exp | mantissa |
1-bit sign-bit
,8-bit biased exponent
(8位多余-127表示法)和剩余的23-bit mantissa
。
当您允许用户选择指数中的位数时,您将不得不返工指数表示法以使用新的用户选择限制。
会有什么变化?
是否会更改sign-bit
处理 - 否。
是否会更改mantissa
处理 - 否
(您仍然会将尾数/有效数转换为&#34;隐藏位&#34;格式)。
因此,您唯一需要关注的是exponent handling
。
你会怎么做?回想一下,当前的8位指数是所谓的多余-127表示法(其中127表示7
位的最大值,允许包含任何偏差并在当前{ {1}}限制。如果您的用户选择6位作为指数大小,那么您必须提供类似的方法以确保您有一个固定数字来表示您的新多余 - ## 符号将在用户限制内工作。
取8-bit
个用户限制,然后可以选择无偏指数值作为6-bit
(可以在31
中表示的最大值)。为此,您可以应用相同的逻辑(以上面的13.25示例)。您对该数字的二进制表示形式为5-bits
,您将小数点1101.01
移至3 positions to the left
,以获得指数偏差1.10101
。
在3
案例中,您需要添加6-bit exponent
以获取指数的3 + 31
:excess-31 notation
,然后将尾数放入&#34;隐藏位&#34 ;格式(即从100010
删除前导1
,从而产生新的自定义Tommy Precision Representation:
1.10101
使用IEEE-754 Tommy Precision Floating Point Representation of (13.25)
0 1 0 0 0 1 0 1 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -|
|s| exp | mantissa |
,1-bit sign-bit
(以6位超出-31表示法)和剩余的6-bit biased exponent
。
相同的规则适用于反转过程以从上面的表示法返回浮点数。 (仅使用25-bit mantissa
代替31
来支持指数的偏差)
希望这在某种程度上有所帮助。如果你真的要允许用户选择的指数大小,我也看不到你能做的其他事情。请记住,IEEE-754标准并没有被猜到,并且很多好的推理和权衡取决于1-8-23符号 - 指数 - 尾数布局。但是,我认为你的练习在要求你坚定地理解标准方面做得很好。
现在完全迷失了,未解决在这个讨论中,这会对这个127
中可以表示的数字范围产生什么影响。我没有看过它,但主要的限制似乎是可以表示的Custom Precision Floating Point Representation
的减少。
答案 3 :(得分:0)
要标准化尾数,请将小数点放在最左边的非零数字的左侧
例如
以标准化形式表示10.11 base 2
= 0.1011 base 2 * 2到第二次幂
两个基数是因为你使用的是二进制数,+ ve 2的幂是因为你将小数点左移了两次。请记住,只有4位用于mantizza
所以mantizza将是1011
答案 4 :(得分:0)
要回答“如何在代码中执行此操作”发布的评论: (假设它是IEEE浮点数)
A)从IEEE float中提取无符号'指数'和'尾数'。
i)exp = 0x7F800000 & yourFloatVar;
//从浮点数中取b1到b8位。 (b0是有符号位,b9和on是尾数)
ii)exp = exp >> 23;
//向右移动,因此这个指数是面向右的
iii)exp += 127;
//添加偏差(127仅适用于32位)
iv)mantissa = 0x007FFFFF & yourFloatVar;
//从float
B)正常化
i)
while(true)
{
if( ((mantissa & 0xC0000000) != 0x80000000)
&&((mantissa & 0xC0000000) != 0x40000000) )
{
mantissa = mantissa << 1;
exponent--;
}
else //AKA the float has been normalized
{
break;
}
}
如果前导2位不是'01'或'10'(这是2的补码的属性 - 标准化的条件),则转移到尾数并递减指数。
我想要注意的是,这并不是最有效的算法;我只是想明确这些步骤。希望我没有错过任何东西!