My question: how to make -2147483648 a positive number in Java?
My thoughts:
There are many ways to make a negative number positive:
Make a negative number positive
however, for the edge case, where the min value of a int in Java is -2147483648, all those methods do not work.
What should I do? Thank you very much!
If you care about it staying an int: you can't. The int primitive fits only values from -2147483648 up to and including 2147483647.
However, if you just want to turn -2147483648 into the integer number 2147483648, then use a long:
public class Test
{
public static void main(String[] args)
{
int v = -2147483648;
long r = -(long)v;
System.out.print(r);
}
}
And done: 2147483648.
Of course, also read through https://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html to get familiar with the limitations of all the primitive data types. And if that still isn't enough and you need arbitrary length integers, BigInteger is available.
My question: how to make -2147483648 a positive number in Java?
There is no value that is representable as an int that is equal to +2147483648.
So the idea of "making -2147483648 positive" as an int has no meaning. You simply cannot do it1.
But you could represent +2147483648 as a long or as a BigInteger (or a few other ways with various caveats.)
What should I do?
Use long (though that has the same issue with Long.MIN_VALUE) or BigInteger or BigDecimal or some other representation.
Or just treat this as a "feature" rather than a problem ... and work around it. For example, remove the sign after you have put it into the StringBuilder or treat -2147483648 as a special case.
1 - It is a mathematical fact that 2's complement signed representations are not symmetric about zero. There is one more negative number ( < 0) than positive ( > 0), and therefore one negative number doesn't have a corresponding positive number.
Related
Lets consider below lines of code.
1- int ExA = Integer.parseInt("123");
2- int ExB = Integer.parseInt("2147483660");
if we execute line 1 than variable ExA will be successfully populated by 123
but if we execute line 2 than we will "NumberFormatException" because in line 2 number provided to the 'parseInt' function is beyond int range.
I am looking for a solution where I can get overflowed int value if we have a number in string format whose value is beyond int range. Please help me figuring out.
You can use BigInteger instead.
BigInteger ExB = new BigInteger("2147483660");
Regarding JDK docs,
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. 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
BigInteger is sometimes messy to implement. You could have a long, and just do Long.parseLong("2147483660"), if it doesn't exceed 2^64.
I'm trying to generate the random number which is stored and I need to return the string value.
Here is My method:
public String generateRand() {
java.util.Random rand = new java.util.Random(System.currentTimeMillis());
String rnd = "" + Math.abs(rand.nextInt()) + "" +
Math.abs(System.currentTimeMillis());
return rnd;
}
The Findbugs plugin of Jenkins is warning me that there is Bad attempt to compute absolute value of signed random integer.
This code generates a random signed integer and then computes the absolute value of that random integer. If the number returned by the random number generator is Integer.MIN_VALUE, then the result will be negative as well, since Math.abs(Integer.MIN_VALUE) == Integer.MIN_VALUE.
Same problem arised for long values as well.
What is the best way to to compute absolute value of signed random integer?
Use
rand.nextInt(Integer.MAX_VALUE);
instead of
Math.abs(rand.nextInt())
Consider a byte. Its value ranges from -128 to 127. Say your byte has a value of -100, then Math.abs(-100) will give you 100. But what if the value of your byte is -128? You cannot represent 128 as a byte, since the maximum value it can represent is 127. So Math.abs() simply returns the negative parameter, unchanged.
The moral of the story is that it's possible for Math.abs() to return a negative value.
Sounds like the plugin recognizes the specific case, Math.abs(rand.nextInt()). So write something different.
The plug-in knows that that case doesn't always work: It knows that rand.nextInt() can sometimes return Integer.MIN_VALUE, and it knows that Math.abs(Integer.MIN_VALUE) can not be computed. I would think about writing my own random number function that does not ever return Integer.MIN_VALUE.
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).
I'm trying to convert a function in java to pl/pgsql, and one problem that I found is when I'm trying to sum 2 negative numbers, and a get a positive number, more specifically :
public void sum(){
int n1 = -1808642602;
int n2 = -904321301;
System.out.println(n1 + n2);// result is 1582003393
}
And in pl/pgsql I get an integer out of range error, and if I change the variables type to bigint i get a normal sum of 2 negative numbers, that is -2712963903, instead of 1582003393
How do I do to pl/pgsql get the same result without printing an integer out of range error?
This happens because the Java int underflows and doesn't tell you.
To get the answer you are looking for in pl, you need to use bigint. Then detect the case when the result is less than Java Integer.MIN_INT (-2^31), which is the case where Java will give a positive result. To get what Java would give you, add 2^32.
You are overflowing the int try the same thing with long and it should work.
It's overflowing, because the result is too big for an int. Use long instead.
Java sums them as 32 bit signed integers, which wrap at -231. Have you tried a 64 bit long instead?
That valid rand of int in Java is -2,147,483,648 to 2,147,483,647 (-2^31 - 2^31-1).
You are causing an Integer underflow. You should use a type long instead of int which ranges from -2^63 to 2^63-1
Java treats those 2 numbers as signed integers.
Basically the scope for singed integers is -2,147,483,648 to 2,147,483,647 (-2^31 - 2^31-1).
Hence the sum of those to values is -2712963903 which is less than the the minimum -2^31 so underflows and then wraps around by doing 2^32 - 2712963903 which gives you the signed int 1582003393.
Try using a long which will not overflow in this case (but will for large enough numbers)
System.out.println((long) n1 + n2);
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.