【问题标题】:java BigInteger conversion algorithmjava BigInteger转换算法
【发布时间】:2019-09-08 04:52:19
【问题描述】:

Java 中的 BigInteger 将数字存储为“无符号整数”数组(它是整数数组,但它们将信息存储在 32 位系统中,然后将其转换为 long 并进行操作)。

它们如何从十进制系统转换为基本的 32 位系统?算法是什么?

我正在阅读资源,但我不明白。我看到他们将数字拆分为 10 位字符串(整数可以处理 1_000_000_000),但接下来呢? 除以 2?还是 2^32 (4294967296)?

感谢您帮助理解它。

【问题讨论】:

  • 谁说他们以 32 位存储这些信息?
  • convert from decimal system to base 32-bit 您是在问如何将基数为 10 的数字转换为基数为 2(二进制)的数字?或者关于浮点表示?问题有点不清楚你在问什么
  • 我在问如何将 String 转换为 BigInteger 内部表示(base 32-bit)
  • BigInteger(或任何地方)中没有“基本 32 位”。内部数字由位表示,BigInteger 只是使用一个 int 数组在需要时向我们的“数字”添加更多位
  • 我同意有一个表示位的整数数组,但后来它们对整个整数进行运算(转换为长整数),因此它们使用基本的 32 位系统。无论如何,他们如何将 String 转换为这么大的位数组???

标签: java algorithm performance biginteger


【解决方案1】:

正确地说,Java 将 BigInteger 存储为 int 数组(Java 没有 unsigned int)。

您有一个数字值,您可以将其存储在任何基数中:基数 2(二进制)、基数 10(十进制)、基数 16(十六进制)或基数 100。Java 将其称为基数。

在任何基础上,该值都保持不变。例如 12(十进制)=1100(二进制)=C(Hex)=C(Base 100)。 为了高效地存储,Java 应该选择一个非常大的基础来:

  • 几乎适合 int 最大值(如果小于该最大值,您将浪费内存。应考虑 int 的几乎所有位)
  • 使用 int 轻松添加该基数的数字而不会溢出(应小于或等于 2^31 的一半)

这就是他们选择以 10^9 为基数来存储它的原因。

Java 实际上使用通用算法来转换除十进制转换之外的任何基数,这涉及计算每个 int 有多少位(给定基数)。但为简单起见,我取十进制,算法是:

 int mag[];
 BigInteger(String decimalDigits){
    mag= new int[size of array enough to store value];
    cut decimalDigits into chunks of 9 digits (the first chunk may have less than 9 digits)
    parse that chunks into integer and save into mag array (in big endian order) 
 }

【讨论】:

  • 每个人都称它为“基数”。这个和其他答案都没有解决多精度转换的问题。它并不像这里所说的那么简单。
  • @user207421:你真的读过这个问题吗? Quincy 要求算法将十进制以存储值转换为 int。
【解决方案2】:

对于非常大的数字,可能会使用一个棘手的分治算法,但除此之外,它就像整数一样:

  1. 将中间结果(一个 BigInteger)设置为 BigInteger.ZERO。
  2. 阅读标志(如果有的话)并记住它
  3. 读取一个数字
  4. 使用给定的数字基数(基数,2..36),将数字转换为二进制,例如以 10 为底,'9' 转换为 9,以 16 为底,'A' 转换为 10,等等。
  5. 将中间结果乘以基数并加上数字的值,因此如果基数为 10,则将中间结果乘以 10 并加上刚刚读取的 9。
  6. 从第 2 点开始重复,直到读取整个字符串
  7. 设置标志
  8. 清理并在必要时删除前导零等。
  9. 将中间 BigInteger 作为函数结果返回。

循环是这样工作的:

number: 1234 (base 10)
intermediate x = 0
read digit = 1: x = x * 10 + 1 = 0 + 1 = 1
read digit = 2: x = x * 10 + 2 = 10 + 2 = 12
read digit = 3: x = x * 10 + 3 = 120 + 3 = 123
read digit = 4: x = x * 10 + 4 = 1230 + 4 = 1234

the same number in base 16:
read digit = 1: x = x * 16 + 1 = 0 + 1 = 1
read digit = 2: x = x * 16 + 2 = 16 + 2 = 18 (= 0x12)
read digit = 3: x = x * 16 + 3 = 288 + 3 = 291 (= 0x123)
read digit = 4: x = x * 16 + 4 = 4656 + 4 = 4660 (= 0x1234)

【讨论】:

  • 这个和另一个答案都没有解决多精度转换的问题。它并不像这里所说的那么简单。
猜你喜欢
  • 2019-03-08
  • 2012-11-30
  • 2015-08-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-10
  • 1970-01-01
相关资源
最近更新 更多