文章目录

  • 一、要求
  • 二、实现原理
  • 三、示例代码
  • 四、测试用例

一、要求

  1. 只能有加减位运算
  2. 支持大数(64位)模积运算(a * b mod m)
  3. 处理模加中的溢出问题 (如果 a + b = c 溢出,则 a + b mod m = c mod m + 2^64 mod m)
  4. 在模数和被模数相差十分大时,快速算出 a mod m

二、实现原理

首先对于mod运算,有以下推导:

模运算转位运算:

  1. 当b为2的整数次幂(即b=1<<k,k为整数)时,满足a % b = a & (b-1) ,且b=1<<k(k为整数)
    例如:num % x10 等于 num & ( x10 - 1 )

加法运算转位运算:

  1. 获取a+b结果中需要进位的位置 : a&b
  2. 获取a+b结果中不进位部分相加的结果 : a^b
  3. 例如:a=010010, b=100111,
    0、每轮首先判断b是否为0,为0则结束,把a的值作为结果返回
    1、(a&b)=000010 得出a+b中需要进位的位置,(a&b)<<1 将进位的值全体左移一位后,表示进位部分进位后的值,a ^ b=110101,表示a+b不进位部分相加的结果。由于(a&b)<<1大于0,把a ^ b的值赋给a,此时a=110101,(a&b)<<1的值赋给b,此时b=000100
    2、上一步获取的a和b继续运算,a ^ b =110001,(a & b)<<1=001000。进位(a & b)<<1大于0,进入下一步,此时,a = a ^ b = 110001,b = (a & b)<<1 = 001000
    3、a ^ b = 111001,(a & b)<<1 = 000000(进位)进位等于0,结束
    最后结果:a = a ^ b = 111001

减法运算转位运算:

  1. a - b = a + (-b) = = a + ~(b - 1) = a + (~b+1)
  2. 然后调用加法运算即可

三、示例代码

#include<stdio.h>//2^64-1
static unsigned long long maxNum = -1;
//2^63
static unsigned long long smaxNum = (unsigned long long) 1 << 63;//得到二进制下数a的第i位的值
unsigned long long bitof(unsigned long long a, unsigned long long i)
{return (a >> i) & 1;
}//模运算
//a和m相差很大时,仍能较快算出 a mod m
unsigned long long mod(unsigned long long a, unsigned long long m)
{unsigned long long m1 = m;while (a >= m){//m1 >= smaxNum 左移后会溢出while (m1 < smaxNum && m1 < a){m1 = m1 << 1;}while (m1 > a && m1 > m){m1 = m1 >> 1;}a -= m1;}return a;
}//模加运算
//( a + b ) mod m = ( a mod m + b mod m ) mod m
//注意 a + b 的溢出
unsigned long long plusmod(unsigned long long a, unsigned long long b, unsigned long long m)
{a = mod(a,m);b = mod(b,m);unsigned long long sum = a + b;//a + b 何时发生溢出,很容易错!!while (a != 0 && b != 0 && b - 1 >= maxNum - a){a = mod(sum,m);b = mod(maxNum,m) + mod(1,m);sum = a + b;}return mod(sum,m);}//模乘运算
// a * b mod m = a * (bnbn-1...b1) mod m
// = ( ∑ a * bi * 2^(i-1) mod m ) mod m
unsigned long long multimod(unsigned long long a, unsigned long long b , unsigned long long m)
{unsigned long long res = 0;int i = 1;for(; i < 64; ++i){if(bitof(a,i) == 0) continue;int j = 0;unsigned long long b1 = b;for (; j < i; ++j){b1 = plusmod(b1,b1,m);}res = plusmod(res,b1,m);}if(bitof(a,0) == 1) res = plusmod(res,b,m);return res;
}

四、测试用例

#include <stdint.h>
#include <stdio.h>
#include <inttypes.h>uint64_t multimod(uint64_t, uint64_t, uint64_t);void test(uint64_t a, uint64_t b, uint64_t m) {#define U64 "%" PRIu64printf(U64 " * " U64 " mod " U64 " = " U64 "\n", a, b, m, multimod(a, b, m));
}int main() {test(123, 456, 789);test(123, 456, -1ULL);test(-2ULL, -2ULL, -1ULL); // should be 1
}

基础算法一:大整数模积运算相关推荐

  1. c语言任意两个整数相减_大整数加减运算的C语言实现

    大整数加减运算的 C 语言实现 一 . 问题提出培训老师给出一个题目:用 C 语言实现一 个大整数计算器.初步要求支持大整数的加.减运算,例如 8888888888888+1112=888888889 ...

  2. 大整数的加减乘除运算

    本关任务: 掌握大整数的基本思想,并运用大整数的基本运算计算出常规整数n的阶乘,然后统计大整数n!中数字0的个数. 相关知识 为了完成本关任务,你需要掌握:1.大整数的思想,2.大整数加法,3.大整数 ...

  3. 高精度算法(大整数的加减乘除运算)

    1.什么是高精度数 ​ 在一般的科学计算中,会经常算到小数点后几百位或者更多,当然也可能是几千亿几百亿的大数字.一般这类数字我们统称为高精度数,高精度算法是用计算机对于超大数据的一种模拟加.减.乘.除 ...

  4. C++ 大整数运算 高精度除法

    前言 这篇文章主要是对于大整数类的设计过程中,如何实现并改进长除法(模拟竖式法)的一个总结. 高精度除法的分类和比较 虽然有些文章在讨论大整数的除法运算时,喜欢分成高精度除以高精度和高精度除以低精度( ...

  5. java 大整数编程_Java编程--RSA算法中的大整数运算

    Java编程–RSA算法中的大整数运算 RSA原理浅析 RSA是利用陷门单向函数实现的,其安全基础依赖于大整数的分解问题的难解性 算法过程 为了加深对RSA算法的了解,接下来通过简单的一个例子来分析一 ...

  6. 蒙哥马利算法求解大整数幂求模

    蒙哥马利大整数模幂算法   前几天写了一篇博客<25行代码实现完整的RSA算法>,是关于用Python代码实现一个完整的RSA算法的代码,整个代码中最核心.最浪费时间的代码部分就是关于求解 ...

  7. 求一个整数的权重 c语言,Code Kata:大整数四则运算—乘法 javascript实现

    上周练习了加减法,今天练习大整数的乘法运算. 采取的方式同样为竖式计算,每一位相乘后相加. 乘法函数: 异符号相乘时结果为负数,0乘任何数都为0 需要调用加法函数 因为输入输出的为字符串,需要去除字符 ...

  8. 山东大学软件工程应用与实践——GMSSL开源库(十)——重要的大整数

    2021SC@SDUSC 文章标题 BIGNUM的结构 大整数的加减法(绝对值加减) 绝对值加减 带符号加减 大整数的乘法 经典乘法 递归和comba乘法 小结 无论是SM2.SM9等国密算法还是以R ...

  9. c语言实验大整数,C语言编写大整数.doc

    C语言编写大整数 本人写的大整数是256进制的,每一个字节里面的每一位都是有用的,因此比较节省空间.前面我用宏定义定义了大整数最大为128字节,也就是1024位,当然你可以改变SIZE的大小来改变大整 ...

最新文章

  1. 赢在中国(08-02-27)
  2. FILA之后又有Amer,安踏能成为“世界的安踏”吗?
  3. 分享Db4o的便捷封装类源码
  4. 分布式事务两阶段提交
  5. PAT 1014 Waiting in Line
  6. GMaps.js:让你快速集成 Google Maps 服务的 jQuery 插件
  7. ajax验证下拉框,ajax 遍历select 下拉框(示例代码)
  8. Java基础-IO流(13)
  9. 英特尔加入 GPU 战局,终用上 6nm 工艺?
  10. 【MySQL】源码安装MySQL
  11. Unity3D入门(二):碰撞检測
  12. 图论——两道并查集例题
  13. Zabbix 3.0安装
  14. 清橙OJ A1036.分解质因数
  15. 使用Cerebro管理ES集群
  16. 初级前端自学react-native,必备知识点(ES6+ReactJS+flexbox)
  17. Java 调用 有道翻译API
  18. 《带你学C带你飞》—— SE54位操作
  19. 反射机制的优点与缺点
  20. 马自达CX-5,中控台的点烟器没电

热门文章

  1. 使用Visual Studio调试BGFX的Shader
  2. java 视频转换 avi 转 MP4
  3. 2计算机电源机,有人说电脑主机电源功率越大越好,2个知识告诉你这观点是片面的...
  4. 10.710.8 基于HyperOpt实现TPE优化基于Optuna实现多种优化
  5. unity访问其他游戏对象的四种方式
  6. esp8266 AMR转PCM
  7. 鸟哥Linux私房菜:第七章笔记
  8. 在小树林飞也能又快又稳,这是港科大沈劭劼组的「猛禽」无人机重规划框架(这也符合我理想中的无人机,而且他们这说明这种室内避障无人机是可以做得很小的。)
  9. python自动化输入文本_python输入文本
  10. 算法分析与设计期末总结