在 C 大型精度类中,您会遇到一个问题,即添加 0xffffffff 和 0x04 结果为 0xffff0003,而不是预期的 0x0100000003。这个问题是由于不正确的进位传播造成的。
为了理解这个问题,让我们检查一下大数相加时的溢出情况。当添加两个无符号字节(或代码中的无符号短整型)并且结果超过最大值 (255) 时,进位标志将设置为 1。此进位应传播到下一个字节,表明结果应增加1.
在您的代码中,当两个字节之和溢出(255)时,您正确设置了进位标志。然而,后续行没有正确传播进位。这是有问题的代码:
if (i < lhs.nbytes) { if (ret.data[i].data == 255 && ret.data[i + 1].carry == 1) increment(&trhs, i + 1); ret.data[i].data += ret.data[i + 1].carry; }
问题 1:
increment(&trhs, i 1) 语句仅在 ret.data[ 时递增 trhs[i 1] i].data == 255 和 ret.data[i 1].carry == 1。但是,进位无论 ret.data[i].data 的值如何,都应该发生传播。
问题 2:
ret.data[i ].data = ret.data[i 1].carry 语句将进位添加到 ret.data[i].data,但这是不正确的。在将结果存储到 ret.data[i].data 之前,应将进位添加到结果中。
解决方案:
要修复进位传播,请执行以下操作更改:
if (i < lhs.nbytes) { ret.data[i].data += ret.data[i + 1].carry; if (ret.data[i].data > 255) { increment(&trhs, i + 1); ret.data[i].data -= 256; // Subtract 256 to adjust for overflow } }
这些更改可确保进位始终正确传播。当两个字节之和超过 255 时,会从 ret.data[i].data 中减去 256 以调整溢出。
以上是为什么我的 C 大精度加法的进位传播不正确?的详细内容。更多信息请关注PHP中文网其他相关文章!