52

How can I get the largest possible value of a BigDecimal variable can hold? (Preferably programmatically, but hardcoding would be ok too)

EDIT
OK, just realized there is no such thing since BigDecimal is arbitrary precision. So I ended up with this, which is sufficiently big for my purpose:
BigDecimal my = BigDecimal.valueOf(Double.MAX_VALUE)

Caner
  • 57,267
  • 35
  • 174
  • 180

5 Answers5

55

Its an arbitrary precision class, it will get as large as you'd like until your computer runs out of memory.

alexblum
  • 2,198
  • 16
  • 13
  • 50
    Not true, it is limited to Integer.MAX_VALUE words. – Andrew Jul 22 '11 at 15:15
  • 2
    Andre, can you explain or give link ? What do you mean by "it is limited to Integer.MAX_VALUE words" ? Thanks – Adelin Mar 10 '14 at 22:42
  • 33
    @Adio, it stores the number using an array of ints. In Java, arrays are indexed by ints, so can have at most Integer.MAX_VALUE entries. So the largest possible BigInteger consumes roughly 8GB of RAM (4 bytes an int * 2GB entries). In a 64-bit JVM, the heap size could be many times that, so available memory is not always the limiting factor to the largest possible BigInteger or BigDecimal. – Simon Kissane Nov 22 '14 at 21:17
  • Hello. I think it requires 8GB of RAM: 2^31-1 (Integer.MAX_VALUE) * 4 bytes (size of integer) = 8589934588 bytes ~= 8GB – HF_ Aug 09 '19 at 14:31
14

Looking at the source BigDecimal stores it as a BigInteger with a radix,

private BigInteger intVal;
private int scale;

and from 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;

So the Largest BigDecimal would be,

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

You can figure out how to set that. :P

[Edit] So just to calculate that, In binary that's,

(2^35)-2 1's (I think?)

in 2's complement

01111111111111111...until your RAM fills up.

Nathan Hughes
  • 94,330
  • 19
  • 181
  • 276
Andrew
  • 13,757
  • 13
  • 66
  • 84
12

Given enough RAM, the value is approximately:

2240*10232

(It's definitely out by a few orders of magnitude but in relative terms it's a very precise estimate.)

biziclop
  • 48,926
  • 12
  • 77
  • 104
  • 1
    May I ask how you came to that value? – Dan Jan 31 '17 at 10:14
  • 1
    I have absolutely no idea, It definitely started with this definition: `The value of the number represented by the BigDecimal is therefore (unscaledValue × 10-scale).`, but I think I calculated with a `byte` backing array for the `BigInteger` storing the unscaled value, instead of an `int`, so I've "slightly" undershot the real limit. – biziclop Jan 31 '17 at 10:33
9

You can represent 2^2147483647-1 however after this value some methods do not work as expected. It has 646456993 digits.

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

prints

2147483647

however

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

prints

-2147483648

as there is an overflow in the number of bits.

BigDecimal.MAX_VALUE is large enough that you shouldn't need to check for it.

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
1

You can store Integer.MAX_VALUE + 1 integers in the magnitude, because arrays count from zero. All those integers got 32 bits, because they're all handled unsigned. So the precision in bits is 32*2147483648 = 68719476736 Bits (=8589934592Byte=8GiB=8,6GB). To get the precision in Decimals, you'll have to multiply the precision in Bits with log10(2) so you'll get 20686623783 full decimal digits, way over 4 times more, than a String can store. Now you can pow 10 with this amount of digits and subtract 1 to get the maximal BigDecimal value, but don't try to calculate it with BigDecimal itself. ;)

But now the question is... What comes first? The method .precision(), which is limited to Integer.MAX_VALUE or my calculated precision?

Spacerat
  • 161
  • 1
  • 3
  • If you can store ```Integer.MAX_VALUE + 1``` entries in an array, what would be the length of the array? The length an integer attribute stored with the array so it can't be mor than ```Integer.MAX_VALUE```. – geanakuch Jul 05 '23 at 11:38