C の大精度クラスで、0xffffffff と 0x04 を加算すると、予期された 0x0100000003 ではなく 0xffff0003 が返されるという問題が発生します。この問題は、桁上げの伝播が正しくないために発生します。
問題を理解するために、大きな数値を加算するときのオーバーフローの状況を調べてみましょう。 2 つの unsigned バイト (またはコード内の unsigned short) が追加され、結果が最大値 (255) を超えると、キャリー フラグが 1 に設定されます。このキャリーは次のバイトに伝播する必要があり、結果が 2 バイト増加する必要があることを示します。 1.
コードでは、2 バイトの合計がオーバーフロー (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 } }
これらの変更により、キャリーが常に正しく伝播されるようになります。 2 バイトの合計が 255 を超える場合、オーバーフローを調整するために ret.data[i].data から 256 が減算されます。
以上がC のラージ精度加算で不正なキャリー伝播が発生するのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。