-1

如何将超大 (>1MB) 十进制数转换为字节/十六进制/二进制?

例如,数字“300”应转换为 {0x01, 0x2C}。字节顺序无关紧要,{0x2C, 0x01} 也可以。

源编号存储在准备好的文件中(没有标点符号、空格或换行符)。最大的刚好超过 17MB,虽然我不能排除我将来会有一个 100MB 的数字。目标也是一个文件。

有没有一种不需要很长时间的方法,或者在需要很长时间的情况下是安全

我担心使用BigInteger会花费很长时间并且不是故障保存(即,如果出现问题,我无法中途恢复)

我并不反对实现我自己的算法,尽管我正在寻找比“检查奇数,除以 2”更有效的方法。我已经看到二进制到 BCD 的非常有效的实现,即Shift 和 Add-3算法,并且正在寻找一种类似有效的反向实现。

对还支持定点数(1 位数字和其余小数,例如Pi)的实现的额外赞誉。

4

2 回答 2

1

对我来说,BigInteger将 1M 位数字转换byte []为大约 39 秒。对你来说太多了吗?

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);

关于小数。让我们假设你有一个大的小数形式<n digits>.<m digits>。您想将其转换为k点后位的二进制。你需要解一个方程:D/(10^m) = X/(2^k),其中 X 是整数。这里 D 是没有点的小数(小数的尾数),X 是没有点的二进制(二进制的尾数)。方程很容易解: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。如果您有数百万位数字,那么您就有数百万次乘法需要对非常大的数执行。

但是,听起来您实际上并没有对这些非常大的数字之一进行转换,您只是猜测这将需要很长时间。在你继续之前,我强烈建议你对这个操作进行基准测试,看看它实际需要多长时间。(米哈伊尔的回答说大约 39 秒,但他编写的代码没有考虑 JVM 预热。)

或者更好的是,使用 BigInteger 对整个应用程序进行编码并对其进行分析以确定是否存在性能问题,以及实际的性能瓶颈在哪里。

于 2013-02-06T14:23:05.307 回答