是否可以用无符号机器字实现扩展欧几里得算法?

问题描述

我正在尝试在不支持 128 位整数的系统上找到一种在 C 中使用 uint64_t 实现 EEA 的方法。问题是,似乎总有某个变量或其他变量溢出的情况,从而产生不正确的结果。

我知道它可以用 /signed/ 机器字完成,这里和其他地方有很多答案提供了伪代码。可以在无符号且无溢出的情况下完成吗?或者您是否需要更大的整数大小?

解决方法

欧几里得算法中的系数在符号上交替(在初始零点消失之后),因此我们可以仅使用幅度来计算它们,并在最后从迭代奇偶校验重建符号。

扩展欧几里得算法求正相对素数uv的乘法逆ab相对于彼此。也就是说,我们找到 ab 使得 au 与 1 modulo v 一致bv 与 1 模 u 一致。我们从两个等式开始:

  • u = 1•u + 0•v
  • v = 0•u + 1•v

那么算法是:

  • xy 是最新两个方程的左边(y 是最新的)。
  • 如果 y 为 1,我们就完成了。右侧uv的系数分别是uv的倒数。立>
  • 否则,让 qx 除以 y 的整数商。附加一个新方程,该方程等于第一个方程减去第二个方程乘以 q

这实现了等式左边的欧几里得算法,所以我们知道对于相对质数 uv,它以 1 终止。那么最后一个方程的形式为:

  • 1 = au + bv

在这里,很明显auv的乘法逆,b是一个bu 的乘法逆。

观察到,在第三个方程中,u 的系数将为 1−0•q。因此,它将是积极的。而 v 的系数将为 0−1•q。因此,它将是负面的。在第四个方程中,u 的系数将为正。从那时起,我们总是从正数中减去负数或从负数中减去正数,因此我们交替使用符号。

在第n个方程中,如果n是奇数,则u的系数是非负的,如果是非正的n 是偶数,反之亦然 v 的系数。

因此,我们可以通过仅保留系数的大小来使用无符号算术来实现这一点:

  • 给定已知非负系数的幅度 g 和已知非正系数的幅度 h,计算新的幅度为 g +hq
  • 给定已知非正系数的幅度 g 和已知非负系数的幅度 h,计算新的幅度为 g +hq

13 和 10 的示例:

  • 13 = 1•13 + 0•10。
  • 10 = 0•13 + 1•10。
  • 13/10 的商是 1。计算 13−1•10 = 3,1+0•1 = 1,0+1•1 = 1。这给出:
  • 3 = 1•13 − 1•10。 (符号是隐式已知的,而不是计算出来的。)
  • 10/3 的商是 3。计算 10−3•3 = 1,0+1•3 = 3,1+1•3 = 4。这给出:
  • 1 = −3•13 + 4•10。

此时,我们用来保存u (13) 系数的任何变量都包含 3,但我们知道它是负数,因为我们处于偶数迭代(第四次)。所以 u 的倒数是 -3。如果需要,我们可以添加 u(计算为 u 减去存储的幅度)以获得正结果。

我已经证明这些计算永远不会超过 u 的系数的 vv 的系数的 u > 但无法获得该证明。 (它嵌入在前任雇主的源代码中。)