-1

符号なし整数値を表す非常に長い2進ワード(> 64ビット)があり、実際の数値を出力したいとします。C ++について話しているので、 bool[]またはstd::vector<bool>またはstd::bitsetで始まり、 std::stringまたはある種のstd::ostreamで終わると仮定しましょう-ソリューションが好むものは何でも。ただし、コア言語とSTLのみを使用してください。

さて、私はそれをチャンクごとに評価して、保存するのに十分小さい中間結果を得る必要があると思いました。x・10kのように10進数が望ましいです。その時点から数を組み立てることができました。しかし、10の底に対応するチャンク幅がないので、それを行う方法がわかりません。もちろん、他のチャンク幅、たとえば3から始めて、x・(2 3kの形式で中間体を取得し、それを基数10に変換することもできますが、これはx・103・になります。 k・lg2は明らかに浮動小数点指数を持っていますが、これは役に立ちません。

とにかく、私はこの数学のがらくたに疲れ果てており、思慮深い提案をいただければ幸いです。

よろしくお願いします、
アーミン

4

1 に答える 1

1

そのようなことを実装することは完全な悪夢であるため、作業する何らかのbignum除算/モジュロ関数が既にあると仮定します。

class bignum {
public:
   bignum(unsigned value=0);
   bignum(const bignum& rhs);
   bignum(bignum&& rhs);
   void divide(const bignum& denominator, bignum& out_modulo);
   explicit operator bool();
   explicit operator unsigned();
};

std::ostream& operator<<(std::ostream& out, bignum value) {
   std::string backwards;
   bignum remainder;
   do {
       value.divide(10, remainder);
       backwards.push_back(unsigned(remainder)+'0');
   }while(value);
   std::copy(backwards.rbegin(), backwards.rend(), std::ostream_iterator(out));
   return out; 
}

丸めがオプションである場合、ほとんどのbignumも同様に変換するのはかなり簡単なはずです。これは非常に高速doubleです。 つまり、64 個の最上位ビットを にコピーし、それを に変換してから、2.0 を有効ビット数から 64 を引いた数で乗じます (先頭のゼロをスキップする必要があるため、有効ビットと呼びます)。150 の有効ビットがあり、上位 64 を にコピーし、それを に変換し、それに~ 7.73e+25 を掛けて結果を取得します。有効ビットが 40 ビットしかない場合でも、右側にゼロを埋め込んでも機能します。40 ビットを の MSB にコピーし、それを に変換し、それに~ 5.96e-8 を掛けて結果を取得します。unsigned longdouble
unsigned longdoublestd::pow(2.0, 150-64)unsigned longdoublestd::pow(2.0, 40-64)

編集

Oli Charlesworth がDouble Dabbleのウィキペディア ページへのリンクを投稿しました。ばかげていると思いませんか。

于 2013-01-04T20:46:18.753 に答える