0

サイズ の 2 つの数値を掛けたいのですが10^10、結果のサイズは10^20です2^66

その数値をCの標準データ型に保存したいのですが、「GNU MP Bignumライブラリ」は使用したくありません。

次の C プログラムが数値を正しく保持しないのはなぜですか?

#include<stdio.h>
typedef long long int ull;
int main(){

    ull n1 = 10000000000LL;
    ull n2 = 10000000000LL;

    printf("%llu",n1*n2);
    return 0;
}

この数値を保持して操作するための最良の方法は何でしょうか?

4

3 に答える 3

6

2 つの値として格納しlong longます。ソリューションのスケッチを次に示します。

#include <stdio.h>

typedef unsigned long long ull;

void multiply( ull a, ull b, ull * lo, ull * hi )
{
  ull ah = a >> 32;
  ull bh = b >> 32;
  ull al = a & 0xFFFFFFFF;
  ull bl = b & 0xFFFFFFFF;

  ull mid = ah * bl + al * bh;
  ull albl = al * bl;

  ull imm = mid + ( albl >> 32 );

  *lo = ( mid << 32 ) + albl;
  *hi = ah * bh + ( imm >> 32 );
}

int main()
{
  ull n1 = 10000000000LL;
  ull n2 = 10000000000LL;

  ull lo, hi;

  multiply( n1, n2, &lo, &hi );

  printf( "result in hex is %llx%016llx\n", hi, lo );
  return 0;
}

出力:

result in hex is 56bc75e2d63100000
于 2013-08-10T19:53:58.250 に答える
2

64 ビット アーキテクチャでlong longは、a の最大値は 2^63-1 です。最大で 32 ビット: 2^32 -1. それよりも大きな数が必要な場合は、問題を解決するためのより良い方法があるかどうかを再評価する必要があります。

より大きな数が必要な場合は、独自のライブラリを作成するか、他の人のライブラリを使用する必要があります。

任意精度の数値を処理する 2 つのライブラリを次に示します。使用できる数値の制限は、それらを保持して計算する必要があるディスク容量、メモリ、および処理能力によって異なります。

GMPMAPM

自分でロールする必要がある場合は、整数の配列に格納できます。64 ビット整数は、2 つの 32 ビット整数にすぎません。1024 ビット整数は、32 個の 32 ビット整数と見なすこともできます。整数の配列を保持するクラスを作成し、必要なサイズにそれらをつなぎ合わせます。難しいのは、整数の配列を加算、減算、乗算、除算できる関数を作成することです。

于 2013-08-10T19:54:07.983 に答える