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;
Related
If I declare a long variable as:
long n = 1E+12L;
The compiler throws a syntax error.
And when I declare it as:
long n = 1E+12;
It throws an incompatible types error.
On the other hand, it is happy to accept two letters in floats and doubles:
double n = 1E+12D;
float n = 1E+12F;
Why is it not working for long literals? do I have to drop the L letter and cast it to long every time?
No, this is not possible. The use of e or E in a numeric literal (i.e. scientific notation) is not allowed by the Java Language Specification for integer literals:
IntegerLiteral:
DecimalIntegerLiteral
HexIntegerLiteral
OctalIntegerLiteral
BinaryIntegerLiteral
DecimalIntegerLiteral:
DecimalNumeral [IntegerTypeSuffix]
...
IntegerTypeSuffix:
(one of)
l L
It is allowed for floating-point literals, but these cannot have an l or L suffix:
FloatingPointLiteral:
DecimalFloatingPointLiteral
HexadecimalFloatingPointLiteral
DecimalFloatingPointLiteral:
Digits . [Digits] [ExponentPart] [FloatTypeSuffix]
. Digits [ExponentPart] [FloatTypeSuffix]
Digits ExponentPart [FloatTypeSuffix]
Digits [ExponentPart] FloatTypeSuffix
ExponentPart:
ExponentIndicator SignedInteger
ExponentIndicator:
(one of)
e E
...
So, you either have to cast from double, or write out your long literal in full. For convenience, though, you can use underscores to group the digits, like 1_000_000_000_000L, in order to make the number of zeros clear.
Why is it not working for long literals?
E or e are not allowed to be used with an int or long. You can use them only with float or double
Please check the following text from the tutorial:
The floating point types (float and double) can also be expressed using E or e (for scientific notation)
do I have to drop the L letter and cast it to long every time?
Yes
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)
I am trying to call a function that requires a short value. The following works:
i.setDamage((short) 10);
However, this does not:
i.setDamage(10S);
According to the IDE I am using, this should work. Why does it not? I am using Maven and Java 7.
According to the Java Language Specification, Section 3.10.1, the only integer type suffix for integer literals is L (or lower case l).
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).
You'll just have to stick with a cast. (Although you may be able to just use the integer literal without a cast if the value is in range.)
According to the Java Language the long value will only hold the suffix of L.
Refer
Java Primitive Data types
JAVA doesn't provide any suffix like S or s for short. You need to cast to shortusing (short)100.
Possible values are
int num = 20; //Decimal
int num = 020; //octal
int num = 0x20; //Hexadecimal
int num = 0b1010; //binary
long num = 563L; //long
In JDK 7, you can embed one or more underscores in an integer literal like
int num = 19_90;
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).
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.