1. 程式人生 > >不超過 $10^{18}$ 的非負整數在模意義下的乘法

不超過 $10^{18}$ 的非負整數在模意義下的乘法

我們 原因 text 這不 導致 turn 浮點 sig double

約定:在博主的校內 OJ 上, long double 類型支持階碼 $15$ 位、有效值 $63$ 位(即科學記數法保留 $64$ 位有效數字)。以下討論以此為前提。

設非負整數 $a, b, p$ 滿足 $a, b<p<2^{63},\ p \ne 0,$ 求 $ab \bmod p.$

$$ab \bmod p=ab-p\left\lfloor {ab \over p} \right\rfloor$$

我們知道 $\left\lfloor {ab \over p} \right\rfloor \leqslant {ab \over p} < p,$ 因此 $\left\lfloor {ab \over p} \right\rfloor$ 可以使用 $64$ 位無符號整數 unsigned long long

存儲。

在計算過程中,我們可能會產生上溢出,且 unsigned long long 上溢出的結果是對 $2^{64}$ 取模,這會導致我們無法還原 $\left\lfloor {ab \over p} \right\rfloor.$

但是,註意到浮點數的精度溢出會在二進制下舍入,規則與“四舍六入五成雙”類似,如果多余的尾數最高位為 $0,$ 就舍去;如果多余的尾數有且僅有最高位為 $1,$ 就向使結果末尾為 $0$ 的方向舍入;否則就進位。

我們考慮使用 long double 來計算 ${ab \over p},$ 然後轉化為 unsigned long long

,通過向 $0$ 取整規則得到 $\left\lfloor {ab \over p} \right\rfloor.$

通過分析,我們得到用 long double 計算 $\left\lfloor {ab \over p} \right\rfloor$ 的誤差不超過 $\pm1.$

最後我們在模 $2^{64}$ 意義下計算 $ab-p\left\lfloor {ab \over p} \right\rfloor$ 得到 $ab \bmod 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},$ 那麽計算 $\left\lfloor q \over p \right\rfloor$ 沒有誤差。
    • 產生誤差的唯一原因是 $q \over p$ 能夠表示為 $2^e(1.\underset{k}{\underbrace{111\cdots1}}0\cdots)_{(2)}\ (k \geqslant 64),$ 即 $2^ep\left( 2^{k+2}-2 \right) \leqslant 2^{k+1}q < 2^ep\left( 2^{k+2}-1 \right).$
    • 當 $e \geqslant 0$ 時,因為 $2^{e+1}p, q$ 是整數,要想 $p\left( 2^{e+1}-2^{e-k} \right) \leqslant q < p\left( 2^{e+1}-2^{e-k-1} \right),$ 必然 $2^{e-k}p \geqslant 1.$ $q \geqslant p\left( 2^{e+1}-2^{e-k} \right)>2^ep \geqslant 2^k \geqslant 2^{64},$ 矛盾。
    • 當 $e<0$ 時,因為 $4p, 2^{-e}q$ 是整數,要想 $p\left(4-2^{-k}\right) \leqslant 2^{-e}q < p\left(4-2^{-1-k}\right),$ 必然 $2^{-k}p \geqslant 1.\ p \geqslant 2^k \geqslant 2^{64},$ 矛盾。
    • 綜上,整數下取整除法沒有誤差。
  • 當 $ab<2^{64}$ 時,計算 $ab$ 沒有誤差,根據上述引理,計算 $\left\lfloor {ab \over p} \right\rfloor$ 也沒有誤差。
  • 當 $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\right)p>p^2>ab \geqslant \left(2x-1\right)2^{e-1} \geqslant \left(2^{64}-1\right)2^{e-1}>\left(2^{63}-1\right)2^e,$ 因此 $\left\lvert 2^ex-ab \right\rvert < p.$ 根據引理 $1,$ 由於 $2^ex$ 和 $x$ 只有階碼上的差別,$\large \left\lfloor {2^ex \over p} \right\rfloor$ 同樣沒有誤差。由此,所有誤差產生於 $\large\frac{ab}p$ 和 $\large\frac{2^ex}p$ 之間的差異,這不超過 $\pm 1.$
  • 博主正在思考還有哪些情況沒有誤差,如果大家知道煩請告訴我;也可以給出導致誤差的反例。
  • 博主的數學很菜,懇求大家檢查並指出上述證明中的錯誤。

不超過 $10^{18}$ 的非負整數在模意義下的乘法