-1

非常に大きな (>1MB) 10 進数をバイト/16 進数/2 進数に変換するにはどうすればよいですか?

たとえば、数値「300」は {0x01, 0x2C} に変換する必要があります。バイトオーダは問わず、{0x2C, 0x01}でもOKです。

ソース番号は準備されたファイルに保存されます (句読点、空白、または改行なし)。最大のものは17MB をわずかに超えていますが、将来的に 100MB になる可能性は否定できません。宛先もファイルです。

時間がかからない方法、または時間がかかった場合に備えてフェイルセーフな方法はありますか?

使用BigIntegerには時間がかかり、フェイルセーブではないのではないかと心配しています(つまり、何か問題が発生した場合、途中で再開できません)

「奇数かどうかをチェックし、2 で割る」よりも効率的なものを探していますが、独自のアルゴリズムの実装に反対しているわけではありません。バイナリから BCD への非常に効率的な実装、Shift および Add-3アルゴリズムを見てきましたが、同様に効率的な実装を逆に探しています。

固定小数点数 (1 桁と残りの 10 進数、たとえばPi)もサポートする実装に対する特別な称賛。

4

2 に答える 2

1

私にとっては、1M桁を〜39秒でBigInteger変換します。byte []それはあなたにとって多すぎますか?

Random r = new Random ();

StringBuilder sb = new StringBuilder();

for (int i = 0; i < 1000000; i++)
    sb.append ("0123456789".charAt(r.nextInt(10)));

long t = System.currentTimeMillis();
BigInteger bi = new BigInteger (sb.toString());
byte [] bytes = bi.toByteArray();
System.out.println(System.currentTimeMillis() - t);

小数について。form に大きな小数があると仮定しましょう<n digits>.<m digits>kドットの後のビットでバイナリに変換したい。方程式を解く必要があります: D/(10^m) = X/(2^k)X は整数です。ここで、D はドットのない 10 進数 (10 進数の仮数)、X はドットのない 2 進数 (2 進数の仮数) です。方程式は簡単に解くことができます: X ~ round(D*(2^k)/(10^m)). X は整数でなければならないので、 を追加しましround()た。

たとえば、12.34 をドットの後に 3 ビットのバイナリに変換する必要があります。

n = 2
m = 2
D = 1234
k = 3
X ~ round(D*(2^k)/(10^m)) = round(1234 * 8 / 100) = round(98.72) = 99 = 1100011b

ドットの後に 3 ビットが必要だったことを思い出してください。したがって、答えは 12.34 ~ 1100.011b です。

これらの計算はすべて、BigInteger を使用して実行できます。

于 2013-02-06T14:14:50.817 に答える
0

時間がかからない方法、または時間がかかった場合に備えてフェイルセーフな方法はありますか?

いいえ。

10 進数を 2 進数に変換するには、大きな数に 10 を繰り返し掛ける必要があります。数百万の桁がある場合は、非常に大きな数に対して数百万の乗算を実行する必要があります。

ただし、これらの非常に大きな数値の 1 つで実際に変換を行っていないようで、長い時間がかかると推測しているだけです。先に進む前に、この操作をベンチマークして、実際にかかる時間を確認することを強くお勧めします。(Mikhail's Answer は ~39 秒と言っていますが、書かれた彼のコードは JVM ウォームアップを考慮していません。)

または、BigInteger を使用してアプリケーション全体をコーディングし、それをプロファイルして、パフォーマンスの問題があるかどうか、および実際のパフォーマンスのボトルネックがどこにあるかを判断することをお勧めします。

于 2013-02-06T14:23:05.307 に答える