账号 自动登录 找回密码 密码 欢迎注册
 搜索

# [求助] 2个64bit的无符号整数相乘，C++如何实现最快？

 如果使用在Linux下编程是可以直接使用128位整数类型的. #include #include #include typedef unsigned __int128 uint128_t; uint128_t mul64(uint64_t a, uint64_t b) {     return (uint128_t)a * b; } // 下面的print_u128_u 代码来自 // https://stackoverflow.com/questions/11656241/how-to-print-uint128-t-number-using-gcc /*      UINT64_MAX 18446744073709551615ULL */ #define P10_UINT64 10000000000000000000ULL   /* 19 zeroes */ #define E10_UINT64 19 #define STRINGIZER(x)   # x #define TO_STRING(x)    STRINGIZER(x) static int print_u128_u(uint128_t u128) {     int rc;     if (u128 > UINT64_MAX)     {         uint128_t leading  = u128 / P10_UINT64;         uint64_t  trailing = u128 % P10_UINT64;         rc = print_u128_u(leading);         rc += printf("%." TO_STRING(E10_UINT64) PRIu64, trailing);     }     else     {         uint64_t u64 = u128;         rc = printf("%" PRIu64, u64);     }     return rc; } int  main() {    uint128_t c;    uint64_t a=10000000000;    uint64_t b=10000000000;    c=mul64(a,b);        int ndigits = print_u128_u(c);    printf("\n%d digits\n", ndigits);    return 0; }复制代码

 还是rust好，原生支持128bit, 随便写一个有符号整数的乘法，是如此的优雅： fn main() {     let x:i128 = -1234567890123456789;     let y:i128 = 12345678901234567891;     println!("{ans}\n{ans:#0128b}", ans = x*y);     println!("{ans}\n{ans:#0128b}", ans = i128::MIN);     println!("{ans}\n{ans:#0128b}", ans = i128::MAX); } 复制代码 (base) [wayne@manjaro rustc]$rustc hello.rs (base) [wayne@manjaro rustc]$ ./hello -15241578753238836751425087877625361999 0b11110100100010001001010000100110001101000001110010101111111010101010101101000100011011000101000000110000111101001100100110110001 -170141183460469231731687303715884105728 0b10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 170141183460469231731687303715884105727 0b1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111复制代码

### 点评

rust大★好，退C包贫鞍  发表于 2020-6-17 15:20

楼主| 发表于 2022-12-29 10:50:43 | 显示全部楼层
 好像使用__uint128_t类型，直接乘就行： #include __uint128_t a; int main() {         a=14757395258967641293;         a=a*14757395258967641293;         printf("%I64u %I64u\n",(unsigned long long)(a>>64),(unsigned long long)(a)); } //运行结果： /* 11805916207174113034 10330176681277348905 -------------------------------- Process exited after 0.01809 seconds with return value 0 */复制代码输出的时候： 1、先右移64位，然后转换成unsigned long long输出，就是高64位 2、直接转换成unsigned long long输出，就是低64位 如果要严格按照楼主的要求，读入2个64位无符号整数，然后输出它们的乘积，就这样写： #include __uint128_t a; unsigned long long x,y,h,l; int main() {         scanf("%I64u %I64u",&x,&y);         a=x;         a=a*y;         h=a>>64;         l=a;         printf("%I64u %I64u\n",h,l); }复制代码运行后输入： 18446744073709551615 18446744073709551615 就得到了这个输出： 18446744073709551614 1 -------------------------------- Process exited after 15.61 seconds with return value 0

 您需要登录后才可以回帖 登录 | 欢迎注册 本版积分规则 回帖并转播 回帖后跳转到最后一页

GMT+8, 2024-7-25 12:18 , Processed in 0.050303 second(s), 15 queries .