__uint128_t乘法结果异常:64位整数相乘输出与预期不符
两个64位整数相乘后输出结果不符的问题
问题详情
我需要实现两个64位整数相乘,把结果拆分到两个64位变量(合计128位)中,为此写了如下函数:
void multiply2(uint64_t a, uint64_t b, uint64_t& hi, uint64_t& lo) { __uint128_t product = static_cast<__uint128_t>(a) * static_cast<__uint128_t>(b); hi = static_cast<uint64_t>(product >> 64); lo = static_cast<uint64_t>(product); }
测试时用了这段代码:
int main(int argc, char* argv[]){ uint64_t a = 4539155444; uint64_t b = 4539155444; uint64_t hi, lo; multiply1(a, b, hi, lo); std::cout << a << " * " << b << " = " << hi << lo << std::endl; return 0;}
实际输出结果:
4539155444 * 4539155444 = 12157188071085285520
但预期的正确输出应该是:
4539155444 * 4539155444 = 20603932144794837136
我找不到问题出在哪。
问题原因及修复
你的multiply2函数逻辑是正确的,问题出在两个地方:
1. 函数调用名称错误
你定义的函数是multiply2,但测试代码里调用的是multiply1——如果没有其他同名函数,这会导致编译错误;如果存在multiply1,那你调用的是错误的函数,自然得不到正确结果。把调用改成multiply2(a, b, hi, lo)即可。
2. 结果输出方式错误
直接把hi和lo按十进制字符串拼接是完全错误的逻辑:hi是乘积的高64位,lo是低64位,正确的完整结果应该是(hi << 64) | lo(以128位整数的形式),而不是把两个数的十进制数字连在一起。
比如修正后的测试代码,需要先把hi和lo合并成128位整数,再实现128位整数的输出(因为标准库没有直接支持__uint128_t的流输出):
#include <iostream> #include <cstring> void multiply2(uint64_t a, uint64_t b, uint64_t& hi, uint64_t& lo) { __uint128_t product = static_cast<__uint128_t>(a) * static_cast<__uint128_t>(b); hi = static_cast<uint64_t>(product >> 64); lo = static_cast<uint64_t>(product); } int main(int argc, char* argv[]){ uint64_t a = 4539155444; uint64_t b = 4539155444; uint64_t hi, lo; multiply2(a, b, hi, lo); // 修正函数调用名称 // 合并hi和lo为完整的128位结果 __uint128_t full_result = (static_cast<__uint128_t>(hi) << 64) | lo; // 自定义函数输出__uint128_t类型 auto print_uint128 = [](__uint128_t val) { if (val == 0) { std::cout << "0"; return; } char buf[40]; // 128位整数最多39位十进制 char* ptr = buf + sizeof(buf) - 1; *ptr = '\0'; while (val > 0) { *--ptr = '0' + (val % 10); val /= 10; } std::cout << ptr; }; std::cout << a << " * " << b << " = "; print_uint128(full_result); std::cout << std::endl; return 0; }
运行这段修正后的代码,就能得到预期的正确输出。
内容的提问来源于stack exchange,提问作者CryptoKitty
相关产品推荐
相关产品推荐

