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