int128的实现

注:计算机计算二进制的乘法和除法的原理和我们计算十进制的一样

设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):

写了一篇最新的相关文章

int128的实现(基本完成)-CSDN博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值