I'm initializing two integers a and b.
It compiles fine for a but there is an error for b.
public class Main_1 {
public static void main(String[] args) {
int a = -2147483648; //Working fine
int b = -(2147483648); //Compilation error: The literal 2147483648 of type int is out of range
}
}
Please help me understand this behavior ?
The reason is that the int datatype has valid values in the range [-2147483648, 2147483647].
When you wrap 2147483648 inside parentheses, it becomes an expression that will be evaluated as an int. However, 2147483648 is too big to fit in an int (too big by one).
The problem does not happen for -2147483648 because it is a valid int value.
Relevant parts of the JLS:
adding parentheses creates a "Parenthesized Expressions" (section 15.8.5)
an integer literal, such as 2147483648, is treated as an int by default (section 3.10.1)
An integer literal is of type long if it is suffixed with an ASCII letter L or l (ell); otherwise it is of type int (§4.2.1).
int values go from -2147483648 to 2147483647. So -(2147483648) is OutOfRange because the value inside the brackets is evaluated as an int. The max value you can put into the brackets is
Integer.MAX_VALUE //Which is equals to 2147483647
The compilation error is pretty clear: you are using the int literal which is out of range. If you really want to do it, you may use long literal:
int b = (int) -(2147483648L);
Or double literal:
int b = (int) -(2147483648.0);
Max value of int is 2147483647 and min value of int is -2147483648. But when you put 2147483648 into braces it initially consider as +2147483648 and it is not in valid for int rage.
A good way to visualize this is to look at (int) -(2147483648) as:
(int) -1 * (2147483648)
When this is evaluated by the compiler, it says, I have to first convert the number in the parenthesis to an integer, then multiply that by negative 1. It then proceeds to do a range check on the number and discovers that it is larger than what can fit in an integer (2147483648), which is the compilation error.
int data type is a 32-bit signed two's complement integer.
Minimum value is - 2,147,483,648.(-2^31)
Maximum value is 2,147,483,647(inclusive).(2^31 -1)
Related
I'm struggling to figure out what the compile/syntax error is in my code.
public class CreditCardValidation {
public static void main (String[] args){
System.out.print(prefixMatched(4388576018402626, 4388));
}
/*
Return the number of digits in d
*/
public static int getSize(long d) {
int size = 0 ;
while( d > 0 ) {
d = d / 10 ;
size = size + 1 ;
}
return size ;
}
/*
Return the first k number of digits from number. If the number of digits in number is
less than k, return the number.
*/
public static long getPrefix(long n, int k) {
int f = getSize(n)-k;
long prefix = n/((int)(Math.pow(10, f)));
return prefix;
}
/*
Return true if the digit d is a prefix for number.
*/
public static boolean prefixMatched( long number, int d ) {
if ( d == getPrefix(number, 4))
return true ;
else
return false ;
}
}
As you can see I'm trying to call prefixMatched to check whether the credit card number meets the requiremen; if digit d is a prefix for number. However, the only thing I get back from the compiler is:
"CreditCardValidation.java:6: integer number too large: 4388576018402626
System.out.print(prefixMatched(4388576018402626, 4388));
^"
I'm sorry if my question is too vauge, this is my first post.
You need to indicate to the compiler that your constant (the CC number) is a long. Put an L on the end of the constant.
It's actually a little easier to treat CC numbers as strings and use charAt(x) to calculate check digits.
The problem is that you are specifying an integer literal 4388576018402626 and that number is larger than the maximum integer, 2147483647.
You are attempting to pass it to a method that takes a long, so make it a long literal by appending L:
System.out.print(prefixMatched(4388576018402626L, 4388));
The JLS specifies this behavior in Section 3.10.1:
An integer literal is of type long if it is suffixed with an ASCII letter L or l (ell); otherwise it is of type int (§4.2.1).
and
It is a compile-time error if a decimal literal of type int is larger than 2147483648 (231), or if the decimal literal 2147483648 appears anywhere other than as the operand of the unary minus operator (§15.15.4).
add L at the end of your literal :
4388576018402626L
You should use Long instead of Integer
int: By default, the int data type is a 32-bit signed two's complement integer, which has a minimum value of -231 and a maximum value of 231-1. In Java SE 8 and later, you can use the int data type to represent an unsigned 32-bit integer, which has a minimum value of 0 and a maximum value of 232-1. Use the Integer class to use int data type as an unsigned integer. Static methods like compareUnsigned, divideUnsigned etc have been added to the Integer class to support the arithmetic operations for unsigned integers.
long: The long data type is a 64-bit two's complement integer. The signed long has a minimum value of -263 and a maximum value of 263-1. In Java SE 8 and later, you can use the long data type to represent an unsigned 64-bit long, which has a minimum value of 0 and a maximum value of 264-1. The unsigned long has a minimum value of 0 and maximum value of 264-1. Use this data type when you need a range of values wider than those provided by int. The Long class also contains methods like compareUnsigned, divideUnsigned etc to support arithmetic operations for unsigned long.
You should use following to avoid exception:
System.out.print(prefixMatched(4388576018402626L, 4388));
The L indicates given value is long. You can use either l or L but I prefer to use L because it looks goods while looking code.
Source: Oracle Docs.
For this code, I would recommend using String instead of dealing with long and int. It's far easier when trying to match the first four digits, which can be isolated easily using String#substring: (String_name).substring(0,4) will be return first four digits of the String. This can then be parsed as an int using Integer#parseInt, or simply compared to another String (if the prefix were a String as well).
Can someone tell me what are the maximum and minimum int values that the Java String.hashCode() method can return?
String.hashCode () return an int calculated by using the below formula:
public int hashCode()
Returns a hash code for this string.
The hash code for a String object is computed as
s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
using int arithmetic, where s[i] is the i-th character of the string, n is the length of the string, and ^ indicates
exponentiation. (The hash value of the empty string is zero.)
The minimum and max value can be found with the below constants.
System.out.println (java.lang.Integer.MAX_VALUE); // 2147483647
System.out.println (java.lang.Integer.MIN_VALUE); // -2147483648
Java int is 4 bytes, signed (two's complement). -2,147,483,648 to 2,147,483,647. Like all numeric types ints may be cast into other numeric types (byte, short, long, float, double). When lossy casts are done (e.g. int to byte) the conversion is done modulo the length of the smaller type.
From the documentation, given that the power to which something is raised depends on the length of the String (which is practically unlimited, as far as I know), I would say that the maximum and minimum must be Integer.MAX_VALUE (2^31 - 1) and Integer.MIN_VALUE (-2^31), respectively.
This number falls into the long range, so why do I get the error:
Exception in thread "main" java.lang.Error: Unresolved compilation problem:
The literal 8751475143 of type int is out of range
Make it
long n = 8751475143L;
L will make it long literal
by default its int
An integer literal is of type long if it is suffixed with an ASCII letter L or l (ell); otherwise it is of type int (§4.2.1). The suffix L is preferred, because the letter l (ell) is often hard to distinguish from the digit 1 (one). [..]
The target of the assignment isn't taken into account when parsing the literal - so you need the L suffix:
long n = 8751475143L;
For the most part - and there are a few notable exceptions - the type of an expression is determined without much reference to its context. So as per section 3.10.1 of the JLS, an integer literal is of type int unless it has an l or L suffix, and the range of an integer literal of type int is of course limited to the range of int itslf.
All numbers in java are treated as integers, unless you say otherwise (or you use a decimal separator - then they are treated as a floats).
So, if you write
long i = 1234;
java will tread the number 1234 as integer, and do the type-cast to long for you.
However, if you type:
long n = 8751475143;
Java cannot treat 8751475143 as integer, because it's out of range. You need to specify, that what you meant was long, by adding 'L' at the end:
long n = 8751475143L;
Primitive Data Types - oracle doc says the range of long in Java is -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807.
But when I do something like this in my eclipse
long i = 12345678910;
it shows me "The literal 12345678910 of type int is out of range" error.
There are 2 questions.
1) How do I initialize the long with the value 12345678910?
2) Are all numeric literals by default of type int?
You should add L: long i = 12345678910L;.
Yes.
BTW: it doesn't have to be an upper case L, but lower case is confused with 1 many times :).
You need to add the L character to the end of the number to make Java recognize it as a long.
long i = 12345678910L;
Yes.
See Primitive Data Types which says "An integer literal is of type long if it ends with the letter L or l; otherwise it is of type int."
You need to add uppercase L at the end like so
long i = 12345678910L;
Same goes true for float with 3.0f
Which should answer both of your questions
To initialize long you need to append "L" to the end.
It can be either uppercase or lowercase.
All the numeric values are by default int. Even when you do any operation of byte with any integer, byte is first promoted to int and then any operations are performed.
Try this
byte a = 1; // declare a byte
a = a*2; // you will get error here
You get error because 2 is by default int.
Hence you are trying to multiply byte with int.
Hence result gets typecasted to int which can't be assigned back to byte.
I am getting a number format exception when trying to do it
int temp = Integer.parseInt("C050005C",16);
if I reduce one of the digits in the hex number it converts but not otherwise. why and how to solve this problem?
This would cause an integer overflow, as integers are always signed in Java. From the documentation of that method (emphasis mine):
An exception of type NumberFormatException is thrown if any of the following situations occurs:
The first argument is null or is a string of length zero.
The radix is either smaller than Character.MIN_RADIX or larger than Character.MAX_RADIX.
Any character of the string is not a digit of the specified radix, except that the first character may be a minus sign '-' ('\u002D') provided that the string is longer than length 1.
The value represented by the string is not a value of type int.
It would fit into an unsigned integer, though. As of Java 8 there's Integer.parseUnsignedInt (thanks, Andreas):
int temp = Integer.parseIntUnsigned("C050005C",16);
On earlier Java versions your best bet here might to use a long and then just put the lower 4 bytes of that long into an int:
long x = Long.parseLong("C050005C", 16);
int y = (int) (x & 0xffffffff);
Maybe you can even drop the bitwise "and" here, but I can't test right now. But that could shorten it to
int y = (int) Long.parseLong("C050005C", 16);
C050005C is 3226468444 decimal, which is more than Integer.MAX_VALUE. It won't fit in int.
Use this:
long temp = Long.parseLong("C050005C",16);
The signed int type ranges from 0x7FFFFFFF to -0x80000000.