我试图将一个int转换为一个自定义浮点数,其中用户指定为exp和尾数保留的位数。我的函数接受一个int value和int exp,将数字表示为 * value * 2exp*。例如,value = 12和exp = 4将返回192。更改这些内容的流程是什么?它是“移动二进制点并调整指数”,但我不知道这是什么意思。我不明白指数偏差是什么。我唯一知道的是,你在指数上加了一个数字,但我不明白为什么。
int value
int exp
b91juud31#
当我们强制浮点数尾数的整数部分为1,小数部分为任意值时,浮点数就是 * 正规化的 *。例如,如果我们取数字13.25,在二进制中是1101.01,1101将是整数部分,而01将是分数部分。我可以将13.25表示为1101.01*(2^0),但它没有被规范化,因为整数部分不是1。但是,如果我们将指数增加1,则允许将尾数右移一位:
1
13.25
1101.01
1101
01
1101.01*(2^0)
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位尾数的示例:
1.10101*(2^3)
1.fffffff * (2^exp)
10100
1.10100
的数据至于指数偏差,让我们看一下标准的32位float,它分为3部分:1个符号位、8个指数位和23个尾数位:
float
s eeeeeeee mmmmmmmmmmmmmmmmmmmmmmm
型指数00000000和11111111有特殊的用途(比如表示Inf和NaN),所以用8个指数位,我们可以表示254个不同的指数,比如说2^1到2^254,但是如果我们想表示2^-3呢?我们如何得到负指数?该格式通过自动从指数中减去127来解决此问题。因此:
00000000
11111111
Inf
NaN
2^1
2^254
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更改为2^-126 ... 2^+127,以便我们可以表示负指数。
2^1 ... 2^254
2^-126 ... 2^+127
mwecs4sa2#
Tommy -- chux和eigenchris,以及其他人沿着提供了很好的答案,但是如果我正确地看待你的评论,你似乎仍然在努力解决“我如何获取这些信息,然后使用这些信息创建一个自定义的浮点表示,其中用户指定指数的位数?“你别难过,前面十几次都是一清二楚,我想我可以试着把它弄清楚。您熟悉IEEE 754-单精度浮点表示:
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。当您允许用户选择指数中的位数时,您将不得不修改指数表示法以使用新的用户选择的限制。
1-bit sign-bit
8-bit biased exponent
23-bit mantissa
这会改变什么
sign-bit
mantissa
所以你唯一需要关注的是exponent handling。你会怎么做?回想一下,当前的8位指数采用的是所谓的excess-127表示法(其中127表示7位的最大值,允许在当前8-bit限制内包含和表示任何偏差。如果您的用户选择6位作为指数大小,那么是什么?您必须提供一个类似的方法,以确保您有一个固定的数字来表示新的**excess-##**表示法,该表示法将在用户限制范围内工作。以6-bit用户限制为例,则可以尝试选择无偏指数值为31(可以用5-bits表示的最大值)。(以上述13.25为例).你的二进制数表示为1101.01,你将十进制数3 positions to the left移动到1.10101,得到3的指数偏差。在6-bit exponent的例子中,你可以添加3 + 31来获得指数的excess-31 notation:100010,然后将尾数放在“隐藏位”格式中(即从1.10101中删除前导1,从而产生新的自定义Tommy Precision表示:
exponent handling
7
8-bit
6-bit
31
5-bits
3 positions to the left
1.10101
3
6-bit exponent
3 + 31
excess-31 notation
100010
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-bit biased exponent(采用6位excess-31表示法)和剩余的25-bit mantissa。同样的规则也适用于从上面的符号中反转浮点数的过程。(只是使用31而不是127来支持指数的偏差)希望这能在某种程度上有所帮助。如果你真的要允许用户选择指数大小,我看不出你还能做什么。记住,IEEE-754标准不是猜测出来的,很多很好的推理和权衡都是为了达到1-8-23符号-指数-尾数布局。然而,我认为你的练习在要求你牢固地理解标准方面做得很好。现在完全丢失和没有解决在这个讨论中,这将对可以在这个Custom Precision Floating Point Representation中表示的数字范围产生什么影响。我没有看过它,但主要的限制似乎是减少了可以表示的MAX/MIN。
6-bit biased exponent
25-bit mantissa
127
Custom Precision Floating Point Representation
MAX/MIN
qqrboqgw3#
“标准化过程”将输入转换为选择范围。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 --> 1.1000...000 binary --> 0.1000...000 stored binary(共23位)exp = 7 --> bias exp 7 + 127 --> 134 decimal --> 10000110 binary存储的二进制模式是“符号”、“隐含前导1位的有效位”和“偏置指数”的级联
1.0 <= s < 2.0
value = 12, exp = 4
value = 12/(2*2*2), exp = 4 + 3
value = 1.5, exp = 7
0 10000110 1000...000 (1 + 8 + 23 = 32 bits)
字符串当有偏指数为0-最小值时,隐含位为0,因此可以存储0.0这样的小数字。当有偏指数为255-最大值时,存储的数据不再表示有限数,而是“无穷大”和“非数字”。查看参考链接了解更多详情。
0
0.0
255
mspsb9vt4#
要回答关于“如何在代码中做到这一点”的评论:(假设它是IEEE float)A)从IEEE浮点数中提取无符号的“指数”和“尾数”。i)exp = 0x7F800000 & yourFloatVar;//从浮点数中获取b1到b8位(b 0是有符号位,b 9是尾数)ii)exp = exp >> 23;//右移,因此该指数是右向的iii)exp += 127;//添加偏置(127仅适用于32位)iv)mantissa = 0x007FFFFF & yourFloatVar;//从float取最后23位B)归一化(一)
exp = 0x7F800000 & yourFloatVar;
exp = exp >> 23;
exp += 127;
mantissa = 0x007FFFFF & yourFloatVar;
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的补码的属性-规格化的条件),则移过尾数并递减指数。我想指出的是,这并不是最有效的算法;我只是想让步骤清楚。希望我没有错过任何东西!
egmofgnx5#
要规范化尾数,请将小数点放在最左边的非零数字的左边例如以标准化形式表示10.11底2= 0.1011基数2 * 2的二次幂2的基数是因为你在处理二进制数,+ve 2的幂是因为你把小数点左移了两次。记住,只有4位用于mantizza所以mantizza应该是1011
5条答案
按热度按时间b91juud31#
当我们强制浮点数尾数的整数部分为
1
,小数部分为任意值时,浮点数就是 * 正规化的 *。例如,如果我们取数字
13.25
,在二进制中是1101.01
,1101
将是整数部分,而01
将是分数部分。我可以将
13.25
表示为1101.01*(2^0)
,但它没有被规范化,因为整数部分不是1
。但是,如果我们将指数增加1,则允许将尾数右移一位:字符串
此表示
1.10101*(2^3)
是13.25
的规范化形式。也就是说,我们知道规范化的浮点数**总是以
1.fffffff * (2^exp)
**的形式出现为了提高效率,我们不需要把
1
的整数部分存储在二进制表示中,我们只是假装它在那里,所以如果我们给予你定制的浮点型尾数5位,我们就会知道10100
位实际上代表的是1.10100
。下面是一个使用标准23位尾数的示例:
的数据
至于指数偏差,让我们看一下标准的32位
float
,它分为3部分:1个符号位、8个指数位和23个尾数位:型
指数
00000000
和11111111
有特殊的用途(比如表示Inf
和NaN
),所以用8个指数位,我们可以表示254个不同的指数,比如说2^1
到2^254
,但是如果我们想表示2^-3
呢?我们如何得到负指数?该格式通过自动从指数中减去127来解决此问题。因此:
0000 0001
将是1 -127 = -126
0010 1101
将是45 -127 = -82
0111 1111
将是127-127 = 0
1001 0010
将是136-127 = 9
这会将指数范围从
2^1 ... 2^254
更改为2^-126 ... 2^+127
,以便我们可以表示负指数。mwecs4sa2#
Tommy -- chux和eigenchris,以及其他人沿着提供了很好的答案,但是如果我正确地看待你的评论,你似乎仍然在努力解决“我如何获取这些信息,然后使用这些信息创建一个自定义的浮点表示,其中用户指定指数的位数?“你别难过,前面十几次都是一清二楚,我想我可以试着把它弄清楚。
您熟悉IEEE 754-单精度浮点表示:
字符串
1-bit sign-bit
、8-bit biased exponent
(以8位多余127表示法)和剩余的23-bit mantissa
。当您允许用户选择指数中的位数时,您将不得不修改指数表示法以使用新的用户选择的限制。
这会改变什么
sign-bit
处理--否。mantissa
处理--否(您仍然会将尾数/有效位转换为“隐藏位”格式)。所以你唯一需要关注的是
exponent handling
。你会怎么做?回想一下,当前的8位指数采用的是所谓的excess-127表示法(其中127表示
7
位的最大值,允许在当前8-bit
限制内包含和表示任何偏差。如果您的用户选择6位作为指数大小,那么是什么?您必须提供一个类似的方法,以确保您有一个固定的数字来表示新的**excess-##**表示法,该表示法将在用户限制范围内工作。以
6-bit
用户限制为例,则可以尝试选择无偏指数值为31
(可以用5-bits
表示的最大值)。(以上述13.25为例).你的二进制数表示为1101.01
,你将十进制数3 positions to the left
移动到1.10101
,得到3
的指数偏差。在
6-bit exponent
的例子中,你可以添加3 + 31
来获得指数的excess-31 notation
:100010
,然后将尾数放在“隐藏位”格式中(即从1.10101
中删除前导1
,从而产生新的自定义Tommy Precision表示:型
使用
1-bit sign-bit
、6-bit biased exponent
(采用6位excess-31表示法)和剩余的25-bit mantissa
。同样的规则也适用于从上面的符号中反转浮点数的过程。(只是使用
31
而不是127
来支持指数的偏差)希望这能在某种程度上有所帮助。如果你真的要允许用户选择指数大小,我看不出你还能做什么。记住,IEEE-754标准不是猜测出来的,很多很好的推理和权衡都是为了达到1-8-23符号-指数-尾数布局。然而,我认为你的练习在要求你牢固地理解标准方面做得很好。
现在完全丢失和没有解决在这个讨论中,这将对可以在这个
Custom Precision Floating Point Representation
中表示的数字范围产生什么影响。我没有看过它,但主要的限制似乎是减少了可以表示的MAX/MIN
。qqrboqgw3#
“标准化过程”将输入转换为选择范围。
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 --> 1.1000...000 binary --> 0.1000...000 stored binary(共23位)
exp = 7 --> bias exp 7 + 127 --> 134 decimal --> 10000110 binary
存储的二进制模式是“符号”、“隐含前导1位的有效位”和“偏置指数”的级联
字符串
当有偏指数为
0
-最小值时,隐含位为0
,因此可以存储0.0
这样的小数字。当有偏指数为
255
-最大值时,存储的数据不再表示有限数,而是“无穷大”和“非数字”。查看参考链接了解更多详情。
mspsb9vt4#
要回答关于“如何在代码中做到这一点”的评论:(假设它是IEEE float)
A)从IEEE浮点数中提取无符号的“指数”和“尾数”。
i)
exp = 0x7F800000 & yourFloatVar;
//从浮点数中获取b1到b8位(b 0是有符号位,b 9是尾数)
ii)
exp = exp >> 23;
//右移,因此该指数是右向的iii)
exp += 127;
//添加偏置(127仅适用于32位)iv)
mantissa = 0x007FFFFF & yourFloatVar;
//从float取最后23位B)归一化
(一)
字符串
如果前导2位不是'01'或'10'(这是2的补码的属性-规格化的条件),则移过尾数并递减指数。
我想指出的是,这并不是最有效的算法;我只是想让步骤清楚。希望我没有错过任何东西!
egmofgnx5#
要规范化尾数,请将小数点放在最左边的非零数字的左边
例如
以标准化形式表示10.11底2
= 0.1011基数2 * 2的二次幂
2的基数是因为你在处理二进制数,+ve 2的幂是因为你把小数点左移了两次。记住,只有4位用于mantizza
所以mantizza应该是1011