Why is BIGInteger in JAVA not responding for higher powers? - java

When I try to find the value of a BigInteger data type for 223,000, I am not able to see the value.
However, for calculations up to 222,000, I could display the BigInteger value without any problems.
Is there any solution or reason for this?

I tried the following in order to make a BigInteger representation of 2^23000:
BigInteger bi = new BigInteger("2");
bi = bi.pow(23000);
System.out.println(bi);
And the number displayed was a very large number spanning 6925 digits. (I won't paste it here as it will span over 100 lines.)
This is with Java 6 SE version 1.6.0_12 in Windows XP.
According the API Specification, BigInteger is an arbitrary-precision integer value which means it should be able to cope with very large integer values.

It works fine for me on GNU/Linux. What do you mean you can't "display" it? What's your code and what error/problem do you get?

this limit for BigInteger is around 2^16 billion, though it has been noted that some functions don't behave correctly after about 2^2 billion.
My guess is that your console or IDE has problems displaying very long lines.

Do you need the whole thing? There is also a BigInteger.modpow(power, modulus) method which raises the integer value to the specified power and returning result % modulus -- commonly used in cryptography. This is also MUCH faster when dealing with very large exponents.

Related

BigInteger > 32 bit left shift issue

I'm looking at BigInteger as a big number (practically) and I'm trying to perform a left shift on the number. So, when I perform a 32 bit left shift on the number (I'm currently using 2), I get the same number again (which is expected for an integer).
Is there any way I can increase the number of bits used to store the number? I know I can use long; however, I want to cross the 64 bit limit. Is there any way I could do that?
It's difficult to say exactly what your problem is without seeing any actual code, but note that BigInteger instances are immutable. If you write aBigInt.shiftLeft(32) the instance referenced by aBigInt is not changed. Instead, a new BigInteger instance with the result of the operation is returned. Try: aBigInt = aBigInt.shiftLeft(32).

Math.pow(10,6) = 999999.999999 on Doogee DG800 Android phone

I know that Math.pow(10,6) performs the computation using doubles which means the precision is not absolute. The current release of Google Authenticator uses following code to compute codes:
int codeLength = 6;
....
int code = truncatedHash % (int) Math.pow(10, codeLength);
Unfortunately at least two Android phones (see google-authenticator issue 396) compute 999999.9999999, which results in incorrect (not working) authentication codes.
The fix is known and it uses a table of integer dividers as the count is limited to 10 possible values (see the fix referenced from the issue).
And here is the question: Is it the application programmer's fault or the library programmer's fault? Should the application programmer expect the correct result (1000000) or must the limited precision be taken into account?
Yes, it's a bug in the library, and it should be reported.
Oracle's Javadoc for Math.pow() says, "If both arguments are integers, then the result is exactly equal to the mathematical result of raising the first argument to the power of the second argument if that result can in fact be represented exactly as a double value."
The word "integer" has special meaning here. A double x is an integer if floor(x) == x.
10.0 is an "integer" by that definition, and so is 6.0, and every integer less than 2^52 can be represented exactly as a double value, so Math.pow(10.0, 6.0) should be exactly equal to 1000000.0.
its the "library programmers fault", incorrectly using math-functions is a beginners' mistake and can never be compensated for in wrapping applications - its basic knowledge that operations on floating-points types never yield exact results, relying on these without using proper delta-comparisons with sensible values INTERNALLY is ... very bad.
I recommend switching the library - if it has flaws like this you can be quite sure that there are also a few more, maybe even security-related bugs.

how to represent 5 billion in java and sequential integer values

I am wondering how to represent 5400000000,5400000001,5400000002,.... in java
(how to represent 5 billion in java)
java ints only hold 2^32-1,
java longs hold 2^64-1,..but i am having a problem representing 5400000000,5400000001,5400000002,....and doubles aren't helping either.
can someone plz provide insight how to represent large values like this (IN JAVA) without having to do multiplication on strings
because Long max = Long(5462205000); just isnt doing it for me.
thx in advance
Your 64-bit integer type can easily hold numbers like 5 billion. Even the signed version can hold values up to 9223372036854775807. Slow bigint libraries not necessary.
To specify these in code you need to use what's called a 'long int literal', which means adding an L to the end of the number. Example:
long x = 5000000000L;
Put an L at the end, e.g.
5400000001L
^
so the compiler knows it's a long
You're having a syntax issue. This will fix your issue nicely:
Long max = new Long(5462205000L);
You need to add the L suffix to indicate this as a Long, otherwise the Java compiler is assuming you're entering an Integer, and this # (anything beyond 2,147,483,647) falls beyond the range of an Integer.

number too large

Hey , i hope i get help with this.
im a coder of a rsps (runescape private server)
and in this game you could like have items and weapons
and the max anmount of a item you can have is 2147000000
and i can change the amount of the max by changing this int
public int maxItemAmount = 2147000000;
and it works
but i want to make it like 3000000000
and i do this
public int maxItemAmount = 3000000000;
and when i compile i get this error
integrer number too large: 3000000000
please guys help me out if you can :)
Integer has an upper bound of 2^31 (2147483648). If you want numbers longer than that, you can use a long or double.
Integers are signed 32-bit values and thus can have a maximum value of 231 = (note that one bit is used for the sign).
You need to change the type of maxItemAmount to long.
you should go for 64 bit types ... i.e: long ...
do ...
public long maxItemAmount = 3000000000L;
A 32-bit signed integer has a range of -232 to 232-1, or − 2,147,483,648 to 2,147,483,647. If you want an integral value outside this range you need to use a 64-bit (long) variable. On the other hand, how likely is it that anyone will have over 2 billion distinct items or weapons? Perhaps, you want to rethink it and keep track of items and their quantities separately. You might also want to consider that changing to use a long may have unexpected consequences if parts of the code assume that it's a 32-bit value.
You can check out the max value of numbers with Integer.MAX_VALUE and Long.MAX_VALUE.
If a long is still not enough for your needs, you can check out the BigInteger class.
Instead of int you should use long. Here you can find more information about the precision of Java primitive data types.
Quoting from the link:
long: The long data type is a 64-bit signed two's complement integer. It has a minimum value of -9,223,372,036,854,775,808 and a maximum value of 9,223,372,036,854,775,807 (inclusive). Use this data type when you need a range of values wider than those provided by int.
As other people has sayed, you have to use another data type that support big numbers.
I recommend you using long. For example:
public long maxItemAmount = 3000000000L;
Notice the L at the end of the value. It tells the runtime that 3000000000 is a long value. Or use:
public long maxItemAmount = new Long("3000000000");
See more info on this page.
Also, someone commented using a BigInteger. It's like a String; don't have limit.
However, I recommend you to use it rarely. A long will probably suit your needs.
EDIT: Strictly speaking, BigIntegers and Strings have limit (see comments).

How do you raise a Java BigInteger to the power of a BigInteger without doing modular arithmetic?

I'm doing some large integer computing, and I need to raise a BigInteger to the power of another BigInteger. The .pow() method does what I want, but takes an int value as an argument. The .modPow method takes a BigInteger as an argument, but I do not want an answer congruent to the value I'm trying to compute.
My BigInteger exponent is too large to be represented as an int, can someone suggest a way to work around this limitation?
You shouldn't try to calculate the power of an extremely large number with another extremely large number. The resulting number would use huge amounts of memory. If you calculate a.pow(b) it will have approximately log(a)*b digits. If b is too large to fit in an integer then for even quite small values of a the result will have several billion digits.
Try to rethink what you are trying to achieve and how to achieve it without doing this operation.
The practical solution is to convert the exponent from a BigInteger to an int.
If you cannot do this because the exponent is too large, your algorithm is unimplementable. The resulting number would almost certainly be too large to represent as a BigInteger. (A BigInteger uses an array of bytes to represent the number, and the maximum size of a Java array is 2**31 - 1 elements no matter how large the heap is.) And even if you implemented a "BiggerInteger" class that would represent the number, you would soon be pushing the limits of the physical memory size of your machine. (And the time taken to do calculate N.pow(M) would be ... NP-tricky ... O((MlogN)^M) I think).
Of course, if the number you are taking the power of is 0, 1 or -1, then the result will easily fit in a BigInteger. But in those cases, there are better ways to calculate the power :-).
You can't find the the value of "Java BigInteger to-the-power BigInteger" because according to JavaDoc "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."
So, Java BigInteger does not support anything above 2^Integer.MAX_VALUE. Tha's why pow method does not take any argument above int.
Hope this answer helps.
Assuming we've already accepted the fact that we shouldn't do this for the reasons outlined in all of the previous answers, here's a working solution that can be used for testing purposes only:
Exponent greater than or equal to 0
BigInteger pow(BigInteger base, BigInteger exponent) {
BigInteger result = BigInteger.ONE;
for (BigInteger i = BigInteger.ZERO; i.compareTo(exponent) != 0; i = i.add(BigInteger.ONE)) {
result = result.multiply(base);
}
return result;
}
This will work for both positive and negative bases. You might want to handle 0 to the power of 0 according to your needs, since that's technically undefined.
Exponent can be both positive or negative
BigDecimal allIntegersPow(BigInteger base, BigInteger exponent) {
if (BigInteger.ZERO.compareTo(exponent) > 0) {
return BigDecimal.ONE.divide(new BigDecimal(pow(base, exponent.negate())), 2, RoundingMode.HALF_UP);
}
return new BigDecimal(pow(base, exponent));
}
This uses the first method to return a BigDecimal with 2 decimal places, you can define the scale and rounding mode as per your needs.
Again, you should not do this in a real-life, production-level system.

Categories

Resources