liangbch 发表于 2020-5-13 11:10:03

如果使用在Linux下编程是可以直接使用128位整数类型的.
#include <stdint.h>
#include <stdio.h>
#include <inttypes.h>

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_ttrailing = 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;
}


intmain()
{
   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;
}

wayne 发表于 2020-6-16 10:36:22

还是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) $ rustc hello.rs
(base) $ ./hello
-15241578753238836751425087877625361999
0b11110100100010001001010000100110001101000001110010101111111010101010101101000100011011000101000000110000111101001100100110110001
-170141183460469231731687303715884105728
0b10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
170141183460469231731687303715884105727
0b1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111

KeyTo9_Fans 发表于 2022-12-29 10:50:43

好像使用__uint128_t类型,直接乘就行:
#include<cstdio>
__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<cstdio>
__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
页: 1 2 [3]
查看完整版本: 2个64bit的无符号整数相乘,C++如何实现最快?