注:计算机计算二进制的乘法和除法的原理和我们计算十进制的一样
设A为128位数,AH为高位的64位,AL为低位的64位
则有:
A / n = (AH / n) << 64 + ((AH % n) << 64 + AL / n)
A * n = (AH * n) << 64 + AL * n
A % n = ((AH % n) << 64 + AL) % n
A + B = (AH + BH) << 64 + AL + AH
其中B为128位,n为int值
这时肯定就有人会说了,这不一看就懂嘛,而且很明显会溢出啊
这就是我们要解决的问题
代码如下:
#include<stdio.h>
#define MAX32 0xFFFFFFFF
#define MAX64_U 0xFFFFFFFF00000000
typedef unsigned long long LLU;//64位
typedef unsigned int U;//32位
typedef struct INT128{
LLU H;
LLU L;
}INT128;
void mutiply_constant(INT128 * A, U n);
void divide_constant(INT128 * A, U n);
U remainder_constant(INT128 * A, U n);
void add_INT128(INT128 * A, INT128 * B);
int main(void)
{
INT128 A;
A.H = 1234567;
A.L = 1234567;
mutiply_constant(&A, 2);
return 0;
}
void mutiply_constant(INT128 * A, U n)
{
LLU A1, A2, A3, A4;
A1 = A2 = A3 = A4 = MAX32;
A1 &= A->H >> 32, A2 &= A->H;
A3 &= A->L >> 32, A4 &= A->L;
A1 *= n, A2 *= n, A3 *= n, A4 *= n;
A->H = (A1 << 32) + A2 + ((A3 & MAX64_U) >> 32);
A->L = (A3 << 32) + A4;
return;
}
void divide_constant(INT128 * A, U n)
{
LLU A1, A2, A3, A4;
A1 = A2 = A3 = A4 = MAX32;
A1 &= A->H >> 32, A2 &= A->H;
A3 &= A->L >> 32, A4 &= A->L;
A2 += (A1 % n) << 32, A1 /= n;
A3 += (A2 % n) << 32, A2 /= n;
A4 += (A3 % n) << 32, A3 /= n;
A4 /= n;
A->H = (A1 << 32) + A2 + ((A3 & MAX64_U) >> 32);
A->L = (A3 << 32) + A4;
return;
}
U remainder_constant(INT128 * A, U n)
{
LLU A1, A2, A3, A4;
A1 = A2 = A3 = A4 = MAX32;
A1 &= A->H >> 32, A2 &= A->H;
A3 &= A->L >> 32, A4 &= A->L;
A2 += (A1 % n) << 32;
A3 += (A2 % n) << 32;
A4 += (A2 % n) << 32;
return A4 % n;
}
void add_INT128(INT128 * A, INT128 * B)
{
LLU A1, A2, A3, A4, B1, B2, B3, B4;
A1 = A2 = A3 = A4 = B1 = B2 = B3 = B4 = MAX32;
A1 &= A->H >> 32, A2 &= A->H, B1 &= B->H >> 32, B2 &= B->H;
A3 &= A->L >> 32, A4 &= A->L, B3 &= B->L >> 32, B4 &= B->L;
A1 += B1, A2 += B2, A3 += B3, A4 += B4;
A->H = (A1 << 32) + A2 + ((A3 & MAX64_U) >> 32);
A->L = (A3 << 32) + A4;
return;
}//结果存在A里面
思路是用4个unsigned long long变量,只用其中的32位来计算
注意:必须是unsigned,因为如果不是的话最高位是符号位,会出事
如果想要记录负数,就模拟二进制的补码吧
最后输出的时候要用高精度数组来转换
更新(2024/2/22):
写了一篇最新的相关文章