What does BigInteger having no limit mean?
There is no theoretical limit. The BigInteger
class allocates as much memory as it needs for all the bits of data it is asked to hold.
There are, however, some practical limits, dictated by the memory available. And there are further technical limits, although you're very unlikely to be affected: some methods assume that the bits are addressable by int
indexes, so things will start to break when you go above Integer.MAX_VALUE
bits.
Is there an upper bound to BigInteger?
The number is held in an int[]
- the maximum size of an array is Integer.MAX_VALUE
. So the maximum BigInteger probably is (2 ^ 32) ^ Integer.MAX_VALUE
.
Admittedly, this is implementation dependent, not part of the specification.
In Java 8, some information was added to the BigInteger javadoc, giving a minimum supported range and the actual limit of the current implementation:
BigInteger
must support values in the range-2
Integer.MAX_VALUE
(exclusive) to+2
Integer.MAX_VALUE
(exclusive) and may support values outside of that range.Implementation note:
BigInteger
constructors and operations throwArithmeticException
when the result is out of the supported range of-2
Integer.MAX_VALUE
(exclusive) to+2
Integer.MAX_VALUE
(exclusive).
What are the limits of BigDecimal and BigInteger?
You won't get NumberFormatException multiplying large numbers. If the number produced is too large, you will get a cryptic NegativeArraySizeException as the size of the array overflows.
You are more likely to get an out of memory error.
The limit is 32 * 2^32-1 bits for BigInteger or about 2^(4 billion).
You can get a NumberFormatException if you
- create a BigInteger from an empty byte[]
- use a signum < -1 or > +1
- try to parse a number in base >36 or < 2
- have a string with illegal digits.
When you get an exception you should also look at the message and the stack trace as this usually gives you the real cause.
BigInteger or not BigInteger?
No, there is not a better solution. If you are working with values that cannot fit into a long or a double then you will need to use a reference type like BigInteger
, and Java does not support operator overloading.
Technically, I suppose you could have some mapping between signed and unsigned values, but if your goal is clean and simple code then this is not at all the way to go.
Does BigInteger not have a maximum length ? If it has how can I find the maximum length of BigInteger datatype?
From Javadoc: Class BigInteger
BigInteger must support values in the range -2 Integer.MAX_VALUE (exclusive) to +2 Integer.MAX_VALUE (exclusive) and may support values outside of that range. An ArithmeticException is thrown when a BigInteger constructor or method would generate a value outside of the supported range. The range of probable prime values is limited and may be less than the full supported positive range of BigInteger. The range must be at least 1 to 2 500000000.
Implementation Note:
In the reference implementation, BigInteger constructors and operations throw ArithmeticException when the result is out of the supported range of -2 Integer.MAX_VALUE (exclusive) to +2 Integer.MAX_VALUE (exclusive).
Not Necessary but here is the code:
// Same can be done for the negative value as well
BigInteger twoBigInteger = BigInteger.valueOf(2);
BigInteger intMaxBigInteger = BigInteger.valueOf(Integer.MAX_VALUE);
BigInteger bigInteger = twoBigInteger.pow(intMaxBigInteger.intValue());
System.out.println(bigInteger.intValue());
Exception:
Exception in thread "main" java.lang.ArithmeticException: BigInteger would overflow supported range
at java.math.BigInteger.reportOverflow(BigInteger.java:1084)
at java.math.BigInteger.checkRange(BigInteger.java:1079)
at java.math.BigInteger.<init>(BigInteger.java:1055)
at java.math.BigInteger.shiftLeft(BigInteger.java:3174)
at java.math.BigInteger.pow(BigInteger.java:2339)
at MyClass.main(MyClass.java:7)
What is the limit of the Value Type BigInteger in C#?
As I can see BigInteger is a ValueType, as much as I know, a ValueType must have a maximum size of 16 bytes.
No, that's not true. It's a conventional limit, but it's entirely feasible for a value type to take more than that. For example:
public struct Foo {
private readonly int a, b, c, d, e; // Look ma, 20 bytes!
}
However, I strongly suspect that BigInteger
actually includes a reference to a byte array:
public struct BigInteger {
private readonly byte[] data;
// Some other fields...
}
(Moslem Ben Dhaou's answer shows one current implementation using int
and uint[]
, but of course the details of this are intentionally hidden.)
So the value of a BigInteger
can still be small, but it can refer to a big chunk of memory - and if there isn't enough memory to allocate what's required when you perform some operation, you'll get an exception.
How could it store such big values, as big as double.MaxValue + double.MaxValue ?
Well BigInteger
is for integers, so I wouldn't particularly want to use it for anything to do with double
... but fundamentally the limitations are going to be around how much memory you've got and the size of array the CLR can cope with. In reality, you'd be talking about enormous numbers before actually hitting the limit for any specific number - but if you have gazillions of smaller numbers, that obviously has large memory requirements too.
I wrote this program to find if a given input is power of 2 , this program is not running for very large number such as 10^18 or so. what should i do
The problem is that 1018 is out of range of Java int
, which stores numbers up to 231-1, or roughly 2*109. You can expand the range of your program by using long
in place of int
to accept numbers up to 9*1018, or to make it accept virtually unlimited range by using BigInteger
:
BigInteger n = new BigInteger(numericString);
BigInteger test = n.and(n.subtract(BigInteger.ONE));
if (test.equals(BigInteger.ZERO)) {
...
}
BigInteger cannot represent infinity
This happened because you exceeded the limit for double
.
Math.Pow
there is evaluated in double
s, so a finite result can only be as big as about 1.7e308, a number you exceed for i = 144
. So it results in double.PositiveInfinity
, which cannot be converted to BigInteger
. BigInteger
has no special representations for infinities the way double
does, it can only store integers and infinity is not an integer - even if BigInteger
had no limit, it would never reach infinity. There is actually also a limit to BigInteger
, when the internal array it uses to store the number reaches its maximum size (you may run out of memory sooner).
In this case you can use BigInteger.Pow
to avoid this, for example
BigInteger sum = 0;
for (int i = 1; i <= 1000; i++)
sum += BigInteger.Pow(i, i);
The result is quite big, as expected.
Related Topics
What's the Point of Guava's Optional Class
Byte Array and Int Conversion in Java
How Does Java's Preparedstatement Work
Java Regex for Support Unicode
What Is the Default Stack Size, Can It Grow, How Does It Work with Garbage Collection
Java Error: "Your Security Settings Have Blocked a Local Application from Running"
Is There a Way in Java to Determine If a Path Is Valid Without Attempting to Create a File
Are Non-Capturing Groups Redundant
How to Write a Key Listener to Track All Keystrokes in Java
Increasing Heap Space in Eclipse: (Java.Lang.Outofmemoryerror)
How to Add a Utf-8 Bom in Java
Programmatically Change Log Level in Log4J2
Stack with Find-Min/Find-Max More Efficient Than O(N)
Copy All Values from Fields in One Class to Another Through Reflection
Why Are Getter and Setter Method Important in Java