不超过 $10^{18}$ 的非负整数在模意义下的乘法

Posted nealchen

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了不超过 $10^{18}$ 的非负整数在模意义下的乘法相关的知识,希望对你有一定的参考价值。

约定:在博主的校内 OJ 上, long double  类型支持阶码 $15$ 位、有效值 $63$ 位(即科学记数法保留 $64$ 位有效数字)。以下讨论以此为前提。

设非负整数 $a, b, p$ 满足 $a, b<p<2^{63}, p e 0,$ 求 $ab mod p.$

$$ab mod p=ab-pleftlfloor {ab over p} ight floor$$

我们知道 $leftlfloor {ab over p} ight floor leqslant {ab over p} < p,$ 因此 $leftlfloor {ab over p} ight floor$ 可以使用 $64$ 位无符号整数 unsigned long long 存储。

在计算过程中,我们可能会产生上溢出,且 unsigned long long 上溢出的结果是对 $2^{64}$ 取模,这会导致我们无法还原 $leftlfloor {ab over p} ight floor.$

但是,注意到浮点数的精度溢出会在二进制下舍入,规则与“四舍六入五成双”类似,如果多余的尾数最高位为 $0,$ 就舍去;如果多余的尾数有且仅有最高位为 $1,$ 就向使结果末尾为 $0$ 的方向舍入;否则就进位。

我们考虑使用 long double 来计算 ${ab over p},$ 然后转化为 unsigned long long,通过向 $0$ 取整规则得到 $leftlfloor {ab over p} ight floor.$

通过分析,我们得到用 long double 计算 $leftlfloor {ab over p} ight floor$ 的误差不超过 $pm1.$

最后我们在模 $2^{64}$ 意义下计算 $ab-pleftlfloor {ab over p} ight floor$ 得到 $ab mod p.$

于是代码就是这么写的:

1 typedef unsigned long long QWORD;
2 QWORD multi(QWORD x, QWORD y, QWORD mod)
3 {
4     return (x*y-(QWORD)((long double)x*y/mod)*mod+mod)%mod;
5 }

 我们来理论验证一下以上细节:

  • 由于 $2^{-64}<{1 over p} leqslant {ab over p}<p<2^{64}$ 并且 $2^e leqslant {ab over p} < 2^{e+1},$ 阶码 $e$ 的范围只有 $[-64, 64)$,完全足够使用。
  • 引理 $1.$ 如果 $1 leqslant p, q<2^{64},$ 那么计算 $leftlfloor q over p ight floor$ 没有误差。
    • 产生误差的唯一原因是 $q over p$ 能够表示为 $2^e(1.underset{k}{underbrace{111cdots1}}0cdots)_{(2)} (k geqslant 64),$ 即 $2^epleft( 2^{k+2}-2 ight) leqslant 2^{k+1}q < 2^epleft( 2^{k+2}-1 ight).$
    • 当 $e geqslant 0$ 时,因为 $2^{e+1}p, q$ 是整数,要想 $pleft( 2^{e+1}-2^{e-k} ight) leqslant q < pleft( 2^{e+1}-2^{e-k-1} ight),$ 必然 $2^{e-k}p geqslant 1.$ $q geqslant pleft( 2^{e+1}-2^{e-k} ight)>2^ep geqslant 2^k geqslant 2^{64},$ 矛盾。
    • 当 $e<0$ 时,因为 $4p, 2^{-e}q$ 是整数,要想 $pleft(4-2^{-k} ight) leqslant 2^{-e}q < pleft(4-2^{-1-k} ight),$ 必然 $2^{-k}p geqslant 1. p geqslant 2^k geqslant 2^{64},$ 矛盾。
    • 综上,整数下取整除法没有误差。
  • 当 $ab<2^{64}$ 时,计算 $ab$ 没有误差,根据上述引理,计算 $leftlfloor {ab over p} ight floor$ 也没有误差。
  • 当 $ab geqslant 2^{64}$ 时,计算 $ab$ 的误差可以这么估计:$2^ex-2^{e-1} leqslant ab leqslant 2^ex+2^{e-1},$ 其中 $2^ex$ 是舍入结果,$2^{63} leqslant x<2^{64}.$ 所以 $left(2^{63}-1 ight)p>p^2>ab geqslant left(2x-1 ight)2^{e-1} geqslant left(2^{64}-1 ight)2^{e-1}>left(2^{63}-1 ight)2^e,$ 因此 $leftlvert 2^ex-ab ight vert < p.$ 根据引理 $1,$ 由于 $2^ex$ 和 $x$ 只有阶码上的差别,$large leftlfloor {2^ex over p} ight floor$ 同样没有误差。由此,所有误差产生于 $largefrac{ab}p$ 和 $largefrac{2^ex}p$ 之间的差异,这不超过 $pm 1.$
  • 博主正在思考还有哪些情况没有误差,如果大家知道烦请告诉我;也可以给出导致误差的反例。
  • 博主的数学很菜,恳求大家检查并指出上述证明中的错误。

以上是关于不超过 $10^{18}$ 的非负整数在模意义下的乘法的主要内容,如果未能解决你的问题,请参考以下文章

c语言编程 求两个超过200位的非负整数的和

AC日记——大整数加法 openjudge 1.6 10

大整数加法

2980 大整数乘法

2981 大整数加法

高精度模板