它的工作原理与小学数学相似,因为你只需知道你的乘法表并记住任何时候零都是零 .
让我拿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.
指数
01111111 2 ^ 0
10000000 2 ^ 1
就像小学一样,我们添加指数2 ^(0 1)= 2 ^ 1 . 然后我们将另一个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,则如果d为1,则ef均为零,则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位的方式进行工作.B . 在其他进位位上开始进行垃圾邮件,数学运算不是您想要手动尝试的 . 这是可能的,但是会产生大量的逻辑,单个时钟乘法器会占用你芯片的很大一部分,有一些技巧......使用一个以上的时钟和一个管道给人一种时钟的错觉......
回到过去的日子里,我们根本无法燃烧那么多的逻辑,我们会说零累加器,然后取ab位和两者都d左移零并加到累加器 . 取b位并且两个都向左移动c并添加到累加器......就像我们做纸和铅笔乘法一样 . 如果你有一个8位* 8位,则只需要乘法至少8个时钟 . 然后归一化等等......
无论如何,您可以看到逻辑中的乘法与我们在小学时学到的相比没有什么不同,因为我们只是乘以0和1.您可以写零或按原样复制操作数 .
简短的回答,您可能错过了隐藏/隐含位的观点,没有理由浪费一点可用于精度的格式 . 当标准化时,IEEE 754对于某些功率是1.mantissa .
双重相同的故事,暗示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总是在尾数乘以时(正常,非零,数字) .
还有其他浮点格式在大多数情况下都是相同的,它们可能更容易用于负数等等(例如,如果你能找到它,请查看ti DSP格式,为速度而不是极端情况而构建) .