如何快速计算大取值ulong类型参数的(a * b) % c运算
64位无符号整数模乘
(a * b) % c最优实现方案 最快方案(.NET 7+ 环境)
直接用.NET 官方提供的硬件加速API即可:
using System.Numerics; ulong MulMod(ulong a, ulong b, ulong mod) { return BitOperations.MultiplyMod(a, b, mod); }
- 这个API底层直接调用CPU的BMI2、ADX等扩展指令实现128位乘积的快速取模,原生支持全范围
ulong输入,包括mod = ulong.MaxValue的极端场景 - 性能是
BigInteger实现的30倍以上,比手写汇编实现还要快1.5倍左右,是目前通用x86/ARM64平台下的最优解
兼容低版本.NET的手写实现(.NET 6及更早)
基于Math.BigMul获取128位乘积的高低位,实现全64位适配的模乘逻辑,代码如下:
ulong MulMod(ulong a, ulong b, ulong mod) { // 边界优化:模为1时结果一定是0 if (mod == 1) return 0; // 获取128位乘积的高64位hi和低64位lo ulong hi = Math.BigMul(a, b, out ulong lo); // 计算(hi * 2^64 + lo) % mod,无位数限制 ulong result = 0; for (int i = 0; i < 64; i++) { result <<= 1; if ((hi & 0x8000000000000000) != 0) result += 1; hi <<= 1; if (result >= mod) result -= mod; } for (int i = 0; i < 64; i++) { result <<= 1; if ((lo & 0x8000000000000000) != 0) result += 1; lo <<= 1; if (result >= mod) result -= mod; } return result; }
- 该实现支持所有
ulong范围的输入参数,不需要限制mod为63位 - 性能比
BigInteger实现高10~15倍,比.NET 7内置API慢2倍左右,适合不能升级运行时的场景
额外性能优化点
- 如果你的场景中
mod是固定值,可以提前预处理mod的逆元,用蒙哥马利模乘进一步把性能提升30%以上 - 所有实现都建议提前校验
mod != 0,避免非法参数异常
内容的提问来源于stack exchange,提问作者Rubiksmaster02
相关产品推荐
相关产品推荐

