这个东西有待考证和优化
代码如下
#include <iostream>
#include <cstdio>
#include <stack>
#include <cstring>
using namespace std;
//从这里到100行都是int128的运算代码
typedef struct _tword
{
unsigned long long rah; //高64位
unsigned long long ral; //低64位
friend bool operator<(const _tword &a, const _tword &b)
{
if (a.rah < b.rah)
return (1);
if (a.rah > b.rah)
return (0);
return (a.ral < b.ral);
}
} tword; //这个结构体就是128位整数了
unsigned long long hbt = 1;
unsigned long long man32; //0~31位全1
unsigned long long man32h; //32~63位全1
void add(tword a, tword b, tword &res)
{
unsigned long long al = a.ral & man32;
unsigned long long ah = (a.ral & man32h) >> 32;
unsigned long long bl = b.ral & man32;
unsigned long long bh = (b.ral & man32h) >> 32;
//因为这里需要处理进位,所以我们要把128位拆成4个32位并把它们扩充至64位,这样就能通过对结果的高32位的处理来加上进位
al += bl;
ah = ah + bh + ((al & man32h) >> 32);
res.rah = a.rah + b.rah + ((ah & man32h) >> 32);
res.ral = ((ah & man32) << 32) | (al & man32);
} //128位加法
void kuomul(unsigned long long a, unsigned long long b, tword &res)
{ //计算64位×64位=128位
unsigned long long al = a & man32;
unsigned long long ah = (a & man32h) >> 32;
unsigned long long bl = b & man32;
unsigned long long bh = (b & man32h) >> 32;
//ah、al为a的高低32位,bh、bl为b的高低32位,则a*b=(ah*bh)<<32+(ah<<32)*bl+(bh<<32)*al+al*bl
unsigned long long albl = al * bl;
unsigned long long ahbh = ah * bh;
unsigned long long albh = al * bh;
unsigned long long ahbl = ah * bl;
tword r1, r2, r3, r4;
r1.rah = ahbh;
r1.ral = 0;
r2.rah = 0;
r2.ral = albl;
r3.ral = (albh & man32) << 32;
r3.rah = (albh & man32h) >> 32;
r4.ral = (ahbl & man32) << 32;
r4.rah = (ahbl & man32h) >> 32;
res.rah = 0;
res.ral = 0;
add(res, r1, res);
add(res, r2, res);
add(res, r3, res);
add(res, r4, res); //把四项相加,得出结果
}
void mul(tword a, int b, tword &res)
{ //128乘int的运算
tword tmp;
unsigned long long ah = a.rah * b;
kuomul(a.ral, b, tmp);
unsigned long long al = tmp.ral;
res.rah = ah + tmp.rah;
res.ral = al;
}
int mod10(tword &hint)
{ //把128位hint除以10,并返回余数
unsigned long long eah = hint.rah / 10;
unsigned long long mod = ((hint.rah % 10) << 32) | ((hint.ral & man32h) >> 32);
unsigned long long low = hint.ral & man32;
hint.rah = eah;
unsigned long long eal = (mod / 10) << 32;
low = low | ((mod % 10) << 32);
eal = eal | (low / 10);
hint.ral = eal;
return (low % 10);
}
stack<char> ss; //字符栈
void print(tword hint)
{ //输出128位整数
if (hint.rah == 0 && hint.ral == 0)
{
printf("0"); //为0直接输出0
}
else
{
while (hint.rah != 0 || hint.ral != 0)
{
ss.push(mod10(hint) + '0');
}
while (!ss.empty())
{
putchar(ss.top());
ss.pop();
}
}
}