【问题标题】:How to get biggest BigDecimal value如何获得最大的 BigDecimal 值
【发布时间】:2011-07-22 15:04:57
【问题描述】:

如何获得 BigDecimal 变量可以容纳的最大可能值? (最好以编程方式,但硬编码也可以)

编辑
好的,刚刚意识到没有这样的事情,因为 BigDecimal 是任意精度。所以我最终得到了这个,这对我的目的来说足够大了:
BigDecimal my = BigDecimal.valueOf(Double.MAX_VALUE)

【问题讨论】:

  • 您需要大量内存才能开始。 ;)
  • @Peter 这意味着没有这样的常量值,因为 BigDecimal 是任意精度,对吧?
  • @LAS_VEGAS 正确,没有这样的事情。你必须选择一个限制,并说这是你最想支持的。
  • 顺便说一下,您可能还想定义允许的最小(正)数,以将每个数字存储的位数限制在合理的内存占用范围内。
  • BigDecimal 可以表示的最大值需要 8 GB 内存。

标签: java math bigdecimal


【解决方案1】:

它是一个任意精度等级,它会变得任意大,直到您的计算机内存不足。

【讨论】:

  • 不正确,仅限于 Integer.MAX_VALUE 个字。
  • 安德烈,你能解释一下或给出链接吗? “它仅限于 Integer.MAX_VALUE 个单词”是什么意思?谢谢
  • @Adio,它使用整数数组存储数字。在 Java 中,数组由整数索引,因此最多可以有 Integer.MAX_VALUE 条目。所以最大可能的 BigInteger 消耗大约 8GB 的​​ RAM(4 字节一个 int * 2GB 条目)。在 64 位 JVM 中,堆大小可能是其数倍,因此可用内存并不总是最大可能的 BigInteger 或 BigDecimal 的限制因素。
  • 你好。我认为它需要 8GB 的​​ RAM:2^31-1 (Integer.MAX_VALUE) * 4 字节(整数大小)= 8589934588 字节 ~= 8GB
【解决方案2】:

查看源 BigDecimal 将其存储为带有基数的 BigInteger,

private BigInteger intVal;
private int scale;

并且来自 BigInteger

/** All integers are stored in 2's-complement form.
63:    * If words == null, the ival is the value of this BigInteger.
64:    * Otherwise, the first ival elements of words make the value
65:    * of this BigInteger, stored in little-endian order, 2's-complement form. */
66:   private transient int ival;
67:   private transient int[] words;

所以最大的 BigDecimal 是,

ival = Integer.MAX_VALUE;
words = new int[Integer.MAX_VALUE]; 
scale = 0;

您可以弄清楚如何设置它。 :P

[编辑] 所以只是为了计算, 在二进制中,

(2^35)-2 个 1(我认为?)

在 2 的补码中

01111111111111111...直到您的 RAM 填满。

【讨论】:

    【解决方案3】:

    给定足够的 RAM,该值约为:

    2240*10232

    (肯定相差几个数量级,但相对而言,这是一个非常精确的估计。)

    【讨论】:

    • 请问您是如何得出这个值的?
    • 我完全不知道,它肯定是从这个定义开始的:The value of the number represented by the BigDecimal is therefore (unscaledValue × 10-scale).,但我想我用 byte 支持数组计算了 BigInteger 存储未缩放的值,而不是int,所以我“略微”低于实际极限。
    【解决方案4】:

    您可以表示 2^2147483647-1,但是在此值之后,某些方法无法按预期工作。它有 646456993 个数字。

    System.out.println(BigInteger.ONE.shiftLeft(Integer.MAX_VALUE)
                                     .subtract(BigInteger.ONE).bitLength());
    

    打印

    2147483647
    

    然而

    System.out.println(BigInteger.ONE.shiftLeft(Integer.MAX_VALUE).bitLength());
    

    打印

    -2147483648
    

    由于位数溢出。

    BigDecimal.MAX_VALUE 足够大,您不需要检查它。

    【讨论】:

      【解决方案5】:

      您可以在幅度中存储 Integer.MAX_VALUE + 1 个整数,因为数组从零开始计数。所有这些整数都有 32 位,因为它们都是无符号处理的。所以位的精度是 32*2147483648 = 68719476736 位(=8589934592Byte=8GiB=8,6GB)。 要获得 Decimals 的精度,您必须将 Bits 的精度乘以 log10(2),这样您将获得 20686623783 个完整的十进制数字,比 String 可以存储的多 4 倍。 现在您可以用这个数字量 pow 10 并减去 1 以获得最大的 BigDecimal 值,但不要尝试使用 BigDecimal 本身来计算它。 ;)

      但现在的问题是……什么是第一? .precision() 方法,限制为 Integer.MAX_VALUE 还是我计算的精度?

      【讨论】:

        猜你喜欢
        • 2021-09-18
        • 2011-07-05
        • 1970-01-01
        • 1970-01-01
        • 2012-09-09
        • 2020-04-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多