I'm having trouble integer parsing 2 strings, and concatenating the contained integers. I find when the integer to be parsed exceeds 5 characters in length, when the button is clicked the program/app crashes.
What can I do to fix this? (to make it work with integers exceeding 5 chars in length)
Code:
public void SimpleButton (View V){
int ab = 123456;
int abc = 223456;
int a = Integer.parseInt(Integer.toString(ab) + Integer.toString(abc));
Toast.makeText(getBaseContext(), String.valueOf(a), Toast.LENGTH_LONG).show();
}
The MAX_VALUE of integer is 2,147,483,647 however when you concatenate the String values you are getting the number 123,456,223,456 which is much larger than the max value for an integer. You must use a Long.
long a = Long.parseLong(Integer.toString(ab) + Integer.toString(abc));
When you concatenate the String forms of the two numbers together, you get a 12-digit number, which is too large to store in an int. The maximum is about 2.1 billion, a 10-digit number. The constant Integer.MAX_VALUE is the maximum possible int, 2147483647.
Parse a long with Long.parseLong, which can handle larger numbers (or reduce the number of digits in ab and/or abc). The constant Long.MAX_VALUE is the maximum possible long, 9223372036854775807L, which is 19 digits.
long a = Long.parseLong(Integer.toString(ab) + Integer.toString(abc));
Related
The following code throws NumberFormatException and I don't understand why,
String sku = "008949679851";
System.out.println(Integer.valueOf(sku));
Interestingly, if I remove the first three digits and the keep the input string as "949679851", then this exception is not thrown. Is there a limit in length when converting a string to an integer value..? How can I make it work with the full string..?
Because the max value of an Integer is Integer.MAX_VALUE = 2147483647 and your number is greater than this 8949679851. Instead use Long.valueOf(sku) or BigInteger for example:
Long l = Long.valueOf(sku);//Max value equal to 9223372036854775807
BigInteger b = new BigInteger(sku);
In Java the maximum value for int and Integers is 2^31-1 (2147483647) so your number exceeds that value.
Java integer size is 32 bits (range -2,147,483,648 to +2,147,483,647). "008949679851" is too long, while "949,679,851" is within the range.
Why if I multiply int num = 2,147,483,647 by the same int num is it returning 1 as result? Note that I am in the limit of the int possible value.
I already try to catch the exception but still give the result as 1.
Before any multiplication java translates ints to binary numbers. So you are actually trying to multiply 01111111111111111111111111111111 by 01111111111111111111111111111111. The result of this is something like
1111111111111111111111111111111000000000000000000000000000000001. The int can hold just 32 bits, so in fact you get 00000000000000000000000000000001 which is =1 in decimal.
In integer arithmetic, Java doesn't throw an exception when an overflow occurs. Instead, it just the 32 least significant bits of the outcome, or equivalently, it "wraps around". That is, if you calculate 2147483647 + 1, the outcome is -2147483648.
2,147,483,647 squared happens to be, in binary:
11111111111111111111111111111100000000000000000000000000000001
The least significant 32 bits of the outcome are equal to the value 1.
If you want to calculate with values which don't fit in 32 bits, you have to use either long (if 64 bits are sufficient) or java.math.BigInteger (if not).
int cannot handle just any large value.Look here. In JAVA you have an exclusive class for this problem which comes quite handy
import java.math.BigInteger;
public class BigIntegerDemo {
public static void main(String[] args) {
BigInteger b1 = new BigInteger("987654321987654321000000000"); //change it to your number
BigInteger b2 = new BigInteger("987654321987654321000000000"); //change it to your number
BigInteger product = b1.multiply(b2);
BigInteger division = b1.divide(b2);
System.out.println("product = " + product);
System.out.println("division = " + division);
}
}
Source : Using BigInteger In JAVA
The Java Language Specification exactly rules what should happen in the given case.
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.
It means, that when you multiply two ints, the result will be represented in a long value first (that type holds sufficient bits to represent the result). Then, because you assign it to an int variable, the lower bits are kept for your int.
The JLS also says:
Despite the fact that overflow, underflow, or loss of information may occur, evaluation of a multiplication operator * never throws a run-time exception.
That's why you never get an exception.
My guess: Store the result in a long, and check what happens if you downcast to int. For example:
int num = 2147483647;
long result = num * num;
if (result != (long)((int)result)) {
// overflow happened
}
To really follow the arithmetics, let's follow the calculation:
((2^n)-1) * ((2^n)-1) =
2^(2n) - 2^n - 2^n + 1 =
2^(2n) - 2^(n+1) + 1
In your case, n=31 (your number is 2^31 - 1). The result is 2^62 + 2^32 + 1. In bits it looks like this (split by the 32bit boundary):
01000000000000000000000000000001 00000000000000000000000000000001
From this number, you get the rightmost part, which equals to 1.
It seems that the issue is because the int can not handle such a large value. Based on this link from oracle regarding the primitive types, the maximum range of values allowed is 2^31 -1 (2,147,483,647) which is exactly the same value that you want to multiply.
So, in this case is recommended to use the next primitive type with greater capacity, for example you could change your "int" variables to "long" which have a bigger range between -2^63 to 2^63-1 (-9223372036854775808 to 9223372036854775807).
For example:
public static void main(String[] args) {
long num = 2147483647L;
long total = num * num;
System.out.println("total: " + total);
}
And the output is:
total: 4611686014132420609
I hope this can help you.
Regards.
According to this link, a Java 'int' signed is 2^31 - 1. Which is equal to 2,147,483,647.
So if you are already at the max for int, and if you multiply it by anything, I would expect an error.
I am making a program and i need a way to make variables go over 10 billion and int only stores up to 999 million for me so i decided to use a long instead of a int and it turn out it only stores up to 999 million as well.
int TotalWorldPop = 7200000000;
gives me the "literal is out of range" error
long TotalWorldPop = 7200000000;
gives me the "literal is out of range" error as well
but
int TotalWorldPop = 999999999
is ok for me
A long can accommodate numbers as large as 263-1. But there's a trick to putting them into the primitive field.
If you're entering the primitive literal, then you have to add an L at the end, as all numeric literals are treated as int (and it can only go up to ~2.1 billion).
If you need numbers larger than that, use BigInteger.
You could use a BigInteger to store very large numbers.
Example:
Biginteger bigInt1 = new Biginteger("91826581752671985235272769716");
Biginteger bigInt2 = new Biginteger("-1796357891266373473772242");
Biginteger bigint3 = bigInt1.divide(bigInt2);
Biginteger bigint4 = bigInt1.add(bigInt2);
I am wanting to store an integer named Amount, I want it to be stored in pence so if the user entered 11.45 it would be stored as 1145. What is the best way to remove the decimal point? Should I be using decimalFormatting in Java?
Edit:
It is entered in string format, was going to covert it to an int. I will give one of your solutions ago and let you know if it works but not sure which one would be the best.. Thanks everyone.
times it by 100 and cast as int. Use decimal formatting is double / float are too inaccurate which they may be for money
If the user input is in the form of a string (and the format has been verified), then you can strip out the decimal point and interpret the result as an integer (or leave it as a string without the decimal point).
String input = "11.45";
String stripped = input.replace(".", ""); // becomes "1145"
int value = Integer.parseInt(stripped);
If it's a float already, then just multiply by 100 and cast, as #user1281385 suggests.
What about convert to float, multiply by 100 and then convert to int?
String pound = "10.45"; // user-entered string
int pence = (int)Math.round(Float.parseFloat(pound) * 100);
This might be also useful: Best way to parseDouble with comma as decimal separator?
Tested and works. Even if the user enters a number without a decimal, it will keep it as such.
double x = 11.45; // number inputted
String s = String.valueOf(x); // String value of the number inputted
int index = s.indexOf("."); // find where the decimal is located
int amount = (int)x; // intialize it to be the number inputted, in case its an int
if (amount != x) // if the number inputted isn't an int (contains decimal)
// multiply it by 10 ^ (the number of digits after the decimal place)
amount = (int)(x * Math.pow(10,(s.length() - 1 - index)));
System.out.print(amount); // output is 1145
// if x was 11.4500, the output is 1145 as well
// if x was 114500, the output is 114500
I'm currently trying to parse some long values stored as Strings in java, the problem I have is this:
String test = "fffff8000261e000"
long number = Long.parseLong(test, 16);
This throws a NumberFormatException:
java.lang.NumberFormatException: For input string: "fffff8000261e000"
However, if I knock the first 'f' off the string, it parses it fine.
I'm guessing this is because the number is large and what I'd normally do is put an 'L' on the end of the long to fix that problem. I can't however work out the best way of doing that when parsing a long from a string.
Can anyone offer any advice?
Thanks
There's two different ways of answering your question, depending on exactly what sort of behavior you're really looking for.
Answer #1: As other people have pointed out, your string (interpreted as a positive hexadecimal integer) is too big for the Java long type. So if you really need (positive) integers that big, then you'll need to use a different type, perhaps java.math.BigInteger, which also has a constructor taking a String and a radix.
Answer #2: I wonder, though, if your string represents the "raw" bytes of the long. In your example it would represent a negative number. If that's the case, then Java's built-in long parser doesn't handle values where the high bit is set (i.e. where the first digit of a 16 digit string is greater than 7).
If you're in case #2, then here is one (pretty inefficient) way of handling it:
String test = "fffff8000261e000";
long number = new java.math.BigInteger(test, 16).longValue();
which produces the value -8796053053440. (If your string is more than 16 hex digits long, it would silently drop any higher bits.)
If efficiency is a concern, you could write your own bit-twiddling routine that takes the hex digits off the end of the string two at a time, perhaps building a byte array, then converting to long. Some similar code is here:
How to convert a Java Long to byte[] for Cassandra?
The primitive long variable can hold values in the range from -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 inclusive.
The calculation shows that fffff8000261e000 hexademical is 18,446,735,277,656,498,176 decimal, which is obviously out of bounds. Instead, fffff8000261e000 hexademical is 1,152,912,708,553,793,536 decimal, which is as obviously within bounds.
As everybody here proposed, use BigInteger to account for such cases. For example, BigInteger bi = new BigInteger("fffff8000261e000", 16); will solve your problem. Also, new java.math.BigInteger("fffff8000261e000", 16).toString() will yield 18446735277656498176 exactly.
The number you are parsing is too large to fit in a java Long. Adding an L wouldn't help. If Long had been an unsigned data type, it would have fit.
One way to cope is to divide the string in two parts and then use bit shift when adding them together:
String s= "fffff8000261e000";
long number;
long n1, n2;
if (s.length() < 16) {
number = Long.parseLong(s, 16);
}
else {
String s1 = s.substring(0, 1);
String s2 = s.substring(1, s.length());
n1=Long.parseLong(s1, 16) << (4 * s2.length());
n2= Long.parseLong(s2, 16);
number = (Long.parseLong(s1, 16) << (4 * s2.length())) + Long.parseLong(s2, 16);
System.out.println( Long.toHexString(n1));
System.out.println( Long.toHexString(n2));
System.out.println( Long.toHexString(number));
}
Note:
If the number is bigger than Long.MAX_VALUE the resulting long will be a negative value, but the bit pattern will match the input.