1

私はCで作業しており、64ビットの数値と128ビットの数値を加算および減算する必要があります。結果は128ビットの数値で保持されます。私は整数配列を使用して、128ビット数の上半分と下半分を格納しています(つまりuint64_t bigNum[2]bigNum[0]は最下位です)。

bigNumを取り込んでそれに加算/減算できる加算および減算関数を誰かが手伝ってもらえuint64_tますか?

私はウェブ上で多くの間違った例を見てきましたので、これを考慮してください:

bigNum[0] = 0;  
bigNum[1] = 1;  
subtract(&bigNum, 1);

この時点bigNum[0]で、すべてのビットが設定されているbigNum[1]必要がありますが、ビットは設定されていないはずです。

4

5 に答える 5

1

これは減算のために働くはずです:

typedef u_int64_t bigNum[2];

void subtract(bigNum *a, u_int64_t b)
{
  const u_int64_t borrow = b > a[1];

  a[1] -= b;
  a[0] -= borrow;
}

加算は非常に似ています。もちろん、上記は明示的なテストで表現することもできますが、常に借用を行う方がクリーンだと思います。最適化は演習として残されました。

bigNum等しい場合{ 0, 1 }、2を引くと等しくなり{ ~0UL, ~0UL }ます。これは、-1を表す適切なビットパターンです。ここで、ULは整数を64ビットにプロモートすると想定されていますが、これはもちろんコンパイラに依存します。

于 2011-01-21T10:09:36.427 に答える
1

多くのアーキテクチャでは、キャリーフラグとフラグ付きの加算/減算命令があるため、任意の長さの整数を加算/減算するのは非常に簡単です。たとえば、x86ではrdx:rax += r8:r9次のように実行できます

add rax, r9
adc rdx, r8

Cでは、このキャリーフラグにアクセスする方法がないため、自分でフラグを計算する必要があります。最も簡単な方法は、符号なしの合計がこのようなオペランドのいずれかよりも小さいかどうかを確認することです。たとえば、a += bこのようにします

aL += bL;
aH += bH + (aL < bL);

アセンブリ出力の例を次に示します

于 2013-08-03T00:45:15.903 に答える
0

減算する値が以下の場合は、bignum[0]に触れる必要はありませんbignum[1]

bignum[0]そうでない場合は、とにかく、からそれを引きます 。この操作はラップアラウンドしますが、これがここで必要な動作です。さらに、から1を実体化する必要がありますbignum[1]

于 2011-01-21T09:55:35.360 に答える
0

ほとんどのコンパイラは、本質的に__int128型をサポートしています。

それを試してみてください、そしてあなたは幸運かもしれません。

于 2011-01-21T10:00:16.230 に答える
0

グレード1または2では、1と10の加算を、10と単位の複数の別々の加算に分割することによって、パーツに分割する方法を学ぶ必要があります。大きな数を扱う場合、同じ原理を適用して、任意の大きな数の算術演算を計算できます。これにより、単位が2 ^ビットの単位になり、「10」が2^ビット大きくなります。

于 2011-01-21T10:01:03.053 に答える