This question already has answers here:
BigInteger.pow(BigInteger)?
(9 answers)
Closed 3 years ago.
I have code that will get the exponent value from given input:
BigInteger a= new BigInteger(2,10);
BigInteger b;
b=a.pow(9999999999);
It is working when value is lower than 7 digits. For example:
BigInteger a= new BigInteger(2,10);
BigInteger b;
b=a.pow(1234567);
Does my code make it possible or is it not possible to have 10 digit in the exponent?
I'm using JDK 1.8.
BigInteger.pow() only exists for int parameters, so you can't take the power bigger than Integer.MAX_VALUE at once.
Those numbers would also be incredibly big (as in "rapidly approaching and passing the number of particles in the observable universe), if you could do it, and there are very few uses for this.
Note that the "power with modulus" operation which is often used in cryptography is implemented using BigInteger.modPow() which does take BigInteger arguments and can therefore handle effectively arbitrarily large values.
pow's parameter is an int. The range of int is -2147483648 to 2147483647, so the answer is it depends on which 10 digits you use. If those 10 digits are 1234567890, that's fine, it's in range (though potentially you'll get a really, really big BigInteger which may push your memory limits); if they're 9999999999 as in your question, that's not fine, it's out of range.
E.g., this compiles:
int a = 1234567890;
This does not:
int b = 9999999999;
^--------------- error: integer number too large: 9999999999
Related
This question already has answers here:
Large Numbers in Java
(6 answers)
Closed 5 years ago.
I've written a method that tests whether a number is prime or not. To maximise the range of numbers that the user can input, I wanted to use doubles. The issue is, after testing it on a very large prime, like 40 digits or so, my method returns false (I've already tested the logic with an int version, and it works just fine as far as I can tell).
Here is my code:
public static boolean isPrime(double number) {
double sqrt = Math.sqrt(number);
for(double i = 2; i<= sqrt; i++) {
if(number%i == 0) {
return false;
}
}
I know the reason it's not working at very high numbers is because of the accuracy error, but is there around this?
I know the reason it's not working at very high numbers is because of the accuracy error, but is there around this?
Yes. Use BigInteger.
Note that long would be better than double, since long can represent all integers up to 2^63 - 1 precisely. By contrast, with double you start losing precision at 2^53 + 1. However neither of these types are suitable for 40 (decimal) digit numbers.
BigInteger arithmetic is significantly slower, but the you will be able to go up to (at least) 2^Integer.MAX_VALUE ... provided that you have enough heap space.
This question already has answers here:
Why, In Java arithmetic, overflow or underflow will never throw an Exception?
(4 answers)
Closed 5 years ago.
I'm doing an AP Comp Sci Review sheet and I do not understand why when I compile
System.out.println(365 * 24 * 3600 * 1024 * 1024 * 1024); the answer is 0. I understand that an int is 32 bits and has a maximum of 2147483647 and could not give you 3386152216166400 but why wouldn't it give an overflow exception error or a similar error?
From the Java Language Specification,
The integer operators do not indicate overflow or underflow in any
way.
That's why you are not getting any exception.
The results are specified by the language as follows,
If an integer multiplication overflows, then the result is the
low-order bits of the mathematical product as represented in some
sufficiently large two's-complement format. As a result, if overflow
occurs, then the sign of the result may not be the same as the sign of
the mathematical product of the two operand values.
Integer.MAX_VALUE + 1 == Integer.MIN_VALUE
Integer.MIN_VALUE - 1 == Integer.MAX_VALUE
That's why you are getting zero as the result.
you have to use BigInteger.
BigInteger bi1, bi2, bi3;
// assign values to bi1, bi2
bi1 = new BigInteger("123");
bi2 = new BigInteger("50");
// perform multiply operation on bi1 using bi2
bi3 = bi1.multiply(bi2);
String str = "Result of multiply is " +bi3;;
// print bi3 value
System.out.println( str );
Just add an L to identify that one of the values is of primitive type long:
System.out.println(365L * 24 * 3600 * 1024 * 1024 * 1024);
/* ^
* 'L' to indicate that one of the factors is long
*/
In Java, all math is done in the largest data type required to handle
all of the current values. So, if you have int * int, it will always
do the math as an integer, but int * long is done as a long.
In this case, the 1024*1024*1024*80 is done as an Int, which overflows
int.
The "L" of course forces one of the operands to be an Int-64 (long),
therefore all the math is done storing the values as a Long, thus no
overflow occurs.
Credit goes to Erich: https://stackoverflow.com/a/1494884/5645656
EDIT:
In many cases Java is based on C or C++ and these are based on
Assembly. An overflow/underflow is silent in C and C++ and almost
silent in assembly (unless you check special flags). This is likely
due to the fact that C and C++ didn't have exceptions when they were
first proposed. If you wanted to see overflows/underflows you just
used a larger type. e.g. long long int or long double ;) BTW assembly
has something similar to exceptions called traps or interrupts,
overflows/underflow doesn't cause a trap AFAIK.
Credit goes to Peter Lawrey: https://stackoverflow.com/a/15998029/5645656
TIP: Sometimes using google can answer your question before you ask it.
This question already has answers here:
How to calculate modulus of large numbers?
(10 answers)
Closed 6 years ago.
for(i=0; i<n+1; i++)
{
y=y+(a[i]*(int)Math.pow(j,i));
}
int r=y/786433;
s[k]=y-(r*786433);
k++;
Now in this code the j value can be 786432. So when I try to get modulus of a number say (1+2*(786432)^2+3*(786432)^3)%786433 then I get -521562 which is not correct I was using modulus operator before too but I got the same answer even with this approach I am getting the same answer. In this approach the modulus of the number is stored in array s[k]. Can anyone help?
If you use Math.pow you are using a double types. Then you convert it back to an int. Rounding can happen and also truncating if values are too big.
To solve this problem You need to use BigInteger:
Immutable arbitrary-precision integers
In particular the method mod:
Returns a BigInteger whose value is (this mod m). This method differs from remainder in that it always returns a non-negative BigInteger.
This question already has answers here:
Division of integers in Java [duplicate]
(7 answers)
Closed 6 years ago.
This feels like a stupid question, but I can't find the answer anywhere in the Java documentation. If I declare two ints and then divide them, what exactly is happening? Are they converted to floats/doubles first, divided, then cast back to an integer, or is the division "done" as integers?
Also, purely from experimentation, integer division seems to round the answer towards zero (i.e. 3/2 = 1 and -3/2 = -1). Am I right in believing this?
They are being divided in integer arithmetics. So dividing integer a by integer b you get how many times b fits into a. Also a % b will give you a remainder of a division. So (a / b ) * b + a % b = a
Java does autoconvert types:
"It autoconverts ints to doubles. It autoconverts shorts and bytes to ints even when no ints are involved, requiring constant annoying casts when you want to do short or byte arithmetic. It autoconverts primitives to wrappers and vice versa for boxing and autoboxing." - user2357112
Java never casts anything without you specifying it.
But still integer / integer = integer.
Also, it does always truncate the result. So if the result would be 0.999999 as float the integer division would still return 0.
This question already has answers here:
Multiplication of two ints overflowing to result in a negative number
(5 answers)
Closed 9 years ago.
public class Test {
public static void main(String[] args) {
int sum=0;
for(int i=1;i<10;i++)
sum = sum+i*i*i*i*i*i*i*i*i*i;
System.out.println(sum);
}
}
OUTPUT:619374629
for(int i=1;i<10;i++)
sum = sum+i*i*i*i*i*i*i*i*i*i*i;
System.out.println(sum);
OUTPUT:
-585353335
In the second output i thought the integer range crossed.But why it is giving -ve number.It need to give me an error.What is the reason for this behaviour?
Thanks in advance...
You have overflowed the size of a 32 bit integer.
Consider what happens when i is equal to 10:
sum = sum + 100000000000 //1 with 11 zeroes
But the maximum positive number that can be stored in a 32 bit integer is only about 2 billion (2 with nine zeroes).
In fact, it gets even worse! The intermediate calculations will be performed with limited precision, and as soon as the multiplication of 10*10*10*10... overflows, then the 10s will be being multiplied with a weird negative number, and be already wrong.
So the number you end up with is not seeming to follow any rules of arithmetic, but in fact it makes perfect sense once you know that primitive integers have limited storage.
The solution is to use 64-bit long and hope you don't overflow THAT too, if you do then you need BigInteger.
Java defines integer math as signed 2s-complement mod 2^32 (for int) and 2^64 (for long). So any time that the result of an int multiply is 2^31 or higher, it wraps around and becomes a negative number. That's just the way integer math works in java.
Java spec
You are using the primitive type. So, when an integer overflows, it will only print out the bits contained in it which is negative. If you want error, try Integer.
As you predicted, you passed the integer range, though causing infinite values (as the sign [the highest bit] gets touched).