2016-04-16 15 views
0

大きな整数でCライブラリを構築しています。基本的には、整数の2進数表現を10進数に変換するための高速なalgorythmを探しています2進数から10進数(巨大数)

JDKのBiginteger.toString()実装を見ましたが、数値を任意の基数に変換する(それは各桁の除算を使用しますが、これは数千桁の数字を処理するのにかなり遅くなるはずです)。

もしあなたがそれについて共有するための文書/知識があれば、私はそれを読むことがうれしいです。

EDIT:

Pで

  • レッツPメモリアドレス

  • Nましょう割り当てられたバイト数である(および設定):私の質問についてもっと精度アドレスPでNバイトで表される整数を変換する方法(リトルエンディアンで簡単にするとします)をCの文字列に変換する方法

    例:

    • N = 1

    • P =いくつかのランダムなメモリアドレスが '00101010'

      ため
    • アウト文字列= "42"

    感謝を保存するあなたのまだ応答する

+0

"バイナリ表現の数値"の例を掲載してください – chux

+0

まさにあなたは何に変換したいのですか?質問のように整数への文字列としての "バイナリ表現"?関数名のような文字列の整数かどうか?または...? – Unimportant

+0

もっと効率的かどうかはわかりませんが、バイナリをBCDに変換する "double dabble"アルゴリズムについてはgoogleを利用できます。 – Marian

答えて

3

理由BigInteger.toStringメソッドが重く見える場合は、変換をチャンクで行います。

些細なアルゴリズムは最後の数字を取り、何も残らないまで大きな整数全体を基数で除算します。これで

一つの問題は、大きな整数の除算は非常に高価であるということですので、番号は(のBigInt部門ではなく)通常の整数の除算で処理できるチャンクに分割されている:言わ

static String toDecimal(BigInteger bigInt) { 
    BigInteger chunker = new BigInteger(1000000000); 
    StringBuilder sb = new StringBuilder(); 
    do { 
    int current = bigInt.mod(chunker).getInt(0); 
    bigInt = bigInt.div(chunker); 
    for (int i = 0; i < 9; i ++) { 
     sb.append((char) ('0' + remainder % 10)); 
     current /= 10; 
     if (currnet == 0 && bigInt.signum() == 0) { 
     break; 
     } 
    } 
    } while (bigInt.signum() != 0); 
    return sb.reverse().toString(); 
} 

、固定基数の場合は、コメントに示唆されているように、 "double dabble"アルゴリズムを必要に応じて移植する方が良いでしょう:https://en.wikipedia.org/wiki/Double_dabble

+0

あなたに2つありがとう、それは私が探していたもの、そして何を理解していなかった私は尋ねていた。私は質問をより明確に編集しました:) –

+1

実際には、これを行う最も良い方法は、分割征服アルゴリズムを使用して、チャンクをより小さなチャンクに再帰的に分割して、方法。それによって多くの部門が節約されます。 My(Delphi)BigInteger.ToString()はそのように機能し、素朴なアプローチよりもはるかに高速になっています。 –

+0

良い点!しかし、それは関係するサイズに依存します... gmpは、サイズが特定のしきい値を超えたときに分割と征服に切り替えるだけです。分割アルゴリズムの概要を熟読することは有益です。もちろん、基数変換は、基数上のコードをテンプレート化することから利益を得る。なぜなら、まともなコンパイラは逆数との乗算による(一定の)基数による除算を実装するからである。ベアメタルレベルでは、少なくともC言語のような言語では、一度に2桁の文字を変換/出力することに別のスピードアップがあります。 – DarthGizka

関連する問題