关于尾数(关于浮点运算的指南),实际上如何将两个尾数相乘?
假设IEEE 754单精度浮点表示。
假设一个数字的尾数为1.5
,将被编码为0b
(十进制为4194304
)。第二个数字的尾数为1.125
,将被编码为0b00100000000000000000000
(十进制为1048576
)。
<代码>1.5 x 1.125=1.6875。
1.6875
编码为0b10110000000000000000000
(十进制为5767168
)。但是4194304 * 1048576
不等于5767168
...
尾数乘法是如何工作的,以至于将4194304(1.5)乘以1048576(1.125),得到5767168(1.6875)?
也就是说,如何将编码的尾数相乘?
一、 e.硬件如何使用存储在内存中的编码尾数来获取新值?
根据指南,浮点数的乘法可以如下实现。我被第二步卡住了。
我发现这段视频回答了我的问题。
为了将编码值相乘,硬件以某种方式忽略了尾随的零。还放置了一个前导位。
因此,对于1.5,使用了0b11(3),而不是0B10000000000000000(4194304)
同样,对于1.125,使用0b1001(9)代替0B001000000000000000(1048576)。
因此,0b11*0b1001=0b11011(27)。
如果忽略0b11011
中的额外前导位*并添加尾随零,则以0b10110000000000000000000
(5767168)结束。
*关于有效位的一些重要信息将在8:05左右解释。对于本例,忽略额外的前导一位就足够了。
您需要产品(1.0*2-1)*(1.0*2-3)。
尾数是1和1,指数是-1和-3。
因此尾数的乘积是1*1=1,指数之和是(-1)-3)=-4。
因此,根据步骤1至步骤4,这两个因素的乘积为1*2-4=0.0625。
需要记住两件重要的事情:(1)二进制IEEE 754浮点中的指数始终表示2的幂,(2)归一化尾数的整数部分始终是1(因此,为什么第一位可以隐藏在数字的实际二进制表示中)。
编辑:自从问题被重写后,我的一些评论被纳入了这个答案。
您链接的指南似乎描述了行为,但没有描述实现。如果实现如此简单,我想浮点数学会和整数数学一样快。
对于尾数,硬件可能会在某个点执行类似于添加回隐藏位的操作,以便
0b110000000000000000000000 * 0b100100000000000000000000 = 0b11011000000000000000000000000000000000000000000
删除隐藏位并舍入尾随位后,该值变为0B10110000000000000。
对于指数,硬件可以从两个因素的偏置指数中减去127,执行算术,然后将127加回总和或差值以重新偏置指数。
请记住,64位格式用于对内存中的数字进行紧凑编码,但这可能不是执行数学时使用的实际表示。处理器甚至可以以80位精度执行中间数学,然后在将值写回内存时将结果四舍五入为64位。请参阅x87 80位双扩展精度。
它的工作原理就像小学数学一样简单得多,因为你只需要知道你的乘法表,并记住任何乘以零的东西都是零。
我取1.5*3.0,单精度。
0x3FC00000 1.5
0x40400000 3.0
0x40900000 1.5 * 3.0 = 4.5
扩大
0x3FC0
0011111111000000
0 01111111 1000000
0x4040
0100000001000000
0 10000000 1000000
所以在二进制中,我们是1.1乘以1.1,就像小学一样,只是更容易
11
* 11
======
11
+11
======
1001
然后我们有一个(不是)十进制(二进制?)从一个操作数到另一个操作数的位置,所以我们的周期在这里是从右开始的两个。
10.01
但我们需要恢复正常
1.001 with an increase in the exponent.
指数
0111111 2^0
10000000 2^1
就像小学一样,我们加上指数2^(0 1)=2^1。然后我们有一个归一化,将一的另一个移位加到指数2^(1 1)=2^2上。
0 10000001 001000....
010000001001000....
0100 0000 1001 000....
给出与计算机生成的结果相匹配的结果
0x40900000
它没有魔力。
硬件乘法和小学乘法没有什么不同,只是简单而已。看看这些单独的位a是位0或1,b是位0或1,依此类推。
ab
* cd
======
ef
gh
======
jklm
如果d是0,那么ef都是零,如果d是1,那么ef=ab,所以到目前为止的方程是
e = a & d
f = b & d
g = a & c
h = b & c
任何带0的都是0,任何带1的都是它自己。
然后我们做加法
nop0
ef
+ gh
======
jklm
我在这里做一些重作弊两位加法,执行和结果,真值表
xy cr
00 00
01 01
10 01
11 10
结果为x或y,执行为x和y
m = f
p = 0 because f+0 cant have a carry bit.
l = e xor h
o = e & h
k = o xor g
n = o & g
j = n
换人,希望我不会再犯任何错误
m = f = b & d
l = e xor h = (a&d) xor (b&c)
k = o xor g = (e & h) xor (a&c) = ((a&d) & (b&c)) xor (a&c)
j = n = o & g = (e & h) & (a&c) = ((a&d) & (b&c)) & (a&c)
因此,这里可能有一些优化,但如果您需要/想要在一个时钟周期内计算两位乘以两位的乘法器,那么就有您的输入和输出方程。很多欺骗,因为做一个3x3,加法会变得更糟。以8位乘以8或32位乘以32的方式工作。进位开始在其他进位的基础上垃圾邮件,数学不是你想手动尝试的东西。这是可能的,但会产生大量的逻辑,单时钟乘法器会消耗芯片的很大一部分,有一些技巧,如。。。使用一个以上的时钟和一根管子,产生一个时钟的错觉。。。
回到以前,我们不能简单地使用太多的逻辑,我们会说一个累加器为零,然后取ab位和两者,d移左零,然后加到累加器中。取ab位和两者,c左移一位,加到累加器中。。。就像我们做纸笔乘法一样。如果您有一个8位*8位,那么乘法至少需要8个时钟。然后是规范化等等。。。
不管怎样,你可以看到,逻辑乘法和我们在小学学到的没有什么不同,只是更简单,因为我们只对0和1进行乘法。要么写零,要么按原样复制操作数。
简而言之,您可能忽略了一点,即存在隐藏/隐含位,没有理由在可用于精度的格式中浪费一点。IEEE 754是1。归一化后尾数为某个幂。
双重相同的故事,暗示1.mantissa:
0x3FF8000000000000 1.5
0x4008000000000000 3.0
0x4012000000000000 4.5
0011111111111000
0100000000001000
0100000000010010
0 01111111111 1000 1.1000...
0 10000000000 1000 1.1000...
0 10000000001 0010 1.0010....
另一种没有小数点的方式来看待这一点(或者暗示它们,我想它们不是小数点,而是二进制点)。
从上面1.10000...*1.10000是0xC00000*0xC00000=0x900000000000, 48位。我们去掉一半的位到0x900000,因为我们有1和47位尾数,但只有23位的空间,所以我们砍掉了24位较低的位,无论是零还是任何其他数字。我们保留一半的位并丢弃一半的位并不是偶然的。现在如果1.000... * 1.000...我们会有0x400000000000 1和46位砍掉23而不是24位。您可以用较小数量的位做一些实验,但请记住,与任何两个N位数字相互复制不同,我们在顶部有一个隐含/固定的1。所以(尾数相乘时1 * 2^23) * (1 * 2^23) = (1*1) * (2^(23 23) = 1 * 2^46总是存在的(对于正常的、非零的数字)。
还有其他浮点格式,在大多数情况下工作相同,他们可能会更容易为负数等(查找tiDSP格式,例如,如果你能找到它,为速度而不是角落的情况)。
本文向大家介绍DSP中浮点转定点运算--定点数的加减乘除运算,包括了DSP中浮点转定点运算--定点数的加减乘除运算的使用技巧和注意事项,需要的朋友参考一下 3.定点数的加减乘除运算 简单的说,各种运算的原则就是先把待运算的数据放大一定的倍数,在运算的过程中使用的放大的数据,在最终需要输出结果的时候再调整回去。 举个例来说,有如下运算: 代码的意思是,该模块需要输出一个整型的结果,但计算的过程中有浮
以下是go中的示例代码: 结果线A1、B1和C1之间的差异是可以理解的。然而,从A2开始到C2魔法来了。来自B2和C2的结果都与来自A2线的结果不匹配。对于x2行(x=A、B或C)也是如此——但是x2和x4的输出是相同的。 为了确保,让我们以二进制形式打印结果。 上面代码中的一些事实(一个在bin表单中): 行A11和C11之间有差异(最后一位数字——就在指数之前)。 行A12和C12几乎相同(除
我阅读关于浮点和舍入在浮点算术期间发生的错误。 我读了很多关于IEEE754单精度/双精度格式的文章。我知道有符号位、8(或)11位指数和23(或)52位有效位以及隐式前导位。 我也知道分母不是质因数2的实数不能完全表示,例如二进制中的0.1是0.0001100110011...... 我知道0.1 0.1 0.1不等于0.3,因为舍入误差的累积。 同样,0.5也可以用二进制格式表示,因为它是1/
本文向大家介绍DSP中浮点转定点运算--定点数模拟浮点数运算及常见的策略,包括了DSP中浮点转定点运算--定点数模拟浮点数运算及常见的策略的使用技巧和注意事项,需要的朋友参考一下 4.定点数模拟浮点数运算及常见的策略 相信大家到现在已经大致明白了浮点数转换成定点数运算的概貌。其实,原理讲起来很简单,真正应用到实际的项目中,可能会遇到各种各样的问题。具我的经验,常见的策略有如下几条: 1)除法转
本文向大家介绍DSP中浮点转定点运算--浮点数的存储格式,包括了DSP中浮点转定点运算--浮点数的存储格式的使用技巧和注意事项,需要的朋友参考一下 二:浮点数的存储格式 2.1 IEEE floating point standard 上面我们说了,浮点数的小数点是不固定的,如果每个人都按照自己的爱好存储在电脑里,那不就乱套了吗?那么怎么在计算机中存储这种类型的数字呢?象这类古老的问题前人早都
对于这些代码行,我得到0作为输出,即它们都是相等的。现在,如果我理解正确,a b和c可能会存储稍微不同版本的真值.3因此,当做一个Float.compare(...)对这些值,我希望得到一个输出值,而不是0。为什么我把它们取为0?