如何安全地乘以一对uint64值才能得到相同类型的LSB和MSB的结果?
typedef struct uint128 {
uint64 lsb;
uint64 msb;
};
uint128 mul(uint64 x, uint64 y)
{
uint128 z = {0, 0};
z.lsb = x * y;
if (z.lsb / x != y)
{
z.msb = ?
}
return z;
}发布于 2020-10-02 21:01:30
正如评论中所说的,最好的解决方案可能是使用一个为您服务的库。但是我会解释你如何在没有图书馆的情况下做到这一点,因为我认为你要求学习一些东西。这可能不是一个非常有效的方法,但它是有效的。
当我们在学校的时候,我们不得不在没有计算器的情况下把两个数字相乘,我们乘以2位数,得到一个1-2位数的结果,然后把它们写下来,最后我们把它们加起来。我们把乘法加起来,所以只需要一次计算一位数的乘法。CPU上的数字越高,也有可能出现类似的情况。但是这里我们不使用十进制数字,而是使用寄存器大小的一半作为数字。有了它,我们可以在一个寄存器中乘2位,变成2位。在小数点13*42中,可以计算为:
3* 2 = 0 6
10* 2 = 2 0
3*40 = 1 2 0
10*40 = 0 4 0 0
--------
0 5 4 6用整数也可以做类似的事情。为了简单起见,我将8位CPU上的2 8位数乘以16位数,因为我一次只把4位数乘以4位。让0x73与0x4F相乘。
0x03*0x0F = 0x002D
0x70*0x0F = 0x0690
0x03*0x40 = 0x00C0
0x70*0x40 = 0x1C00
-------
0x22BD基本上创建一个包含4个元素的数组,在您的示例中,每个元素都具有uint32_t类型,在数组的正确元素中存储或添加单个乘法的结果,如果单个乘法的结果对于单个元素来说太大,则将较高的位存储在较高的元素中。如果一个加法溢出了1到下一个元素。最后,您可以将数组的两个元素组合成两个uint64_t。
https://stackoverflow.com/questions/64177052
复制相似问题