Which one of there expressions are considered java long literals:
1) 0Xf000L
2) 6L
3) (489 - 0L) / 80
4) 30508600000
5) 0XBD000
My answer:
1) is considered because of "L" a the end
2) Same as first
3) is not a literal but one calculation ?
4) is to large number for long
5) is not long literal
If I am wrong somewhere please correct me. Also, if the long variable that we are initialising doesn't have "L" at the end is it still considered long literal ? Because if I do that in the compiler it lets me do it(for example 5. question) Thanks!
For 1) and 2) you are completely correct, they are long literals.
3), correct: This is a constant expression of type long. Even though it is a compile-time constant, it does not count as a literal.
4) No, this is not too large to fit in a long. However, since it does not have the L suffix, it doesn’t count as a long. It’s an int, but at the same time too large to fit in an int, so as discussed in the comments, it’s a compile-time error.
5) is an int literal. It can be used wherever a long value is expected (e.g., assigned to a long variable), but you are correct, this doesn’t make it a long literal.
The basic rule is as RealSkeptic said: “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).” (here quoted from JLS section 3.10.1).
(And just to get on a soapbox, the quote continues: The suffix L is preferred, because the letter l (ell) is often hard to distinguish from the digit 1 (one).)
Related
I am working with data types at the moment in Java, and if I have understood correctly the type long accepts a value between the ranges of -9,223,372,036,854,775,808 to +9,223,372,036,854,775,807. Now as you can see below, I have create a long variable called testLong, although when I insert 9223372036854775807 as the value, I get an error stating:
The literal 9223372036854775807 of the type int is out of range.
I don't know why it is referring to the long data type as an int.
Anyone have any ideas?
Code:
char testChar = 01;
byte testByte = -128;
int testInt = -2147483648;
short testShort = -32768;
long testLong = 9223372036854775807;
float testFoat;
double testDouble = 4.940656458412;
boolean testBool = true;
Add a capital L to the end:
long value = 9223372036854775807L;
Otherwise, the compiler will try to parse the literal as an int, hence the error message
I don't know why it is referring to the long data type as an int
It is not. You should learn to trust compiler messages (especially when they are from sane, modern compilers and not ancient compilers that tended to have bad error messages). While the language that they speak might be hard to decipher at times, they are not usually lying to you.
Let's look at it again:
The literal of int 9223372036854775807 is out of range.
Note, that it doesn't mention your variable testLong or the type long anywhere, so the problem is not about the initialization. It seems to occur at some other point.
Now lets investigate some of the parts of the message:
int tells us that he wants to treat something as an int value (which is not what you wanted!)
"out of range" is pretty clear: something is not within the expected range (probably that of int)
"The literal": now that's interesting: what is a literal?
I'll leave the cozy list to talk about literals for a moment: literals are places where you have some value in your code. There are String literals, int literals, class literals and so on. Every time you mention a value explicitly in your code, it's a literal.
So it's not actually nagging you about the variable declaration, but the number itself, the value is what it's nagging you about.
You can easily verify this by using the same literal in a context where a long and an int are equally acceptable:
System.out.println(9223372036854775807);
PrintStream.println can take either an int or a long (or pretty much anything else). So that code should be fine, right?
No. Well, maybe it should be, but according to the rules it is not fine.
The problem is that "some digits" is defined to be an int literal and therefore must be in the range defined by int.
If you want to write a long literal, then you must make that explicit by appending the L (or lower case l, but I highly suggest you always use the upper-case variant, because it's much easier to read and harder to mistake for a 1).
Note that a similar problem occurs with float (postfix F/f) and double (postfix D/d).
Side note: you'll realize that there are no byte or short literals and you can still assign values (usually int literals) to byte and short variables: that's possible due to special rules in § 5.2 about conversions in an Assignment Contexts: they allow assignment of constant expressions of a larger type to byte, short, char or int if the values are within the types range.
Try doing 9223372036854775807L. The L at the end tells Java that 9223372036854775807 is a long.
I had this problem in the past and I fixed that by writing the value in the scientific form.
for example:
double val = 9e300;
long ak = 34778754226788444L/l;
Both use but at a time only one use uppercase L or lowercase l.
Why use L/l? Because long is a part of integral datatype.
I am working with data types at the moment in Java, and if I have understood correctly the type long accepts a value between the ranges of -9,223,372,036,854,775,808 to +9,223,372,036,854,775,807. Now as you can see below, I have create a long variable called testLong, although when I insert 9223372036854775807 as the value, I get an error stating:
The literal 9223372036854775807 of the type int is out of range.
I don't know why it is referring to the long data type as an int.
Anyone have any ideas?
Code:
char testChar = 01;
byte testByte = -128;
int testInt = -2147483648;
short testShort = -32768;
long testLong = 9223372036854775807;
float testFoat;
double testDouble = 4.940656458412;
boolean testBool = true;
Add a capital L to the end:
long value = 9223372036854775807L;
Otherwise, the compiler will try to parse the literal as an int, hence the error message
I don't know why it is referring to the long data type as an int
It is not. You should learn to trust compiler messages (especially when they are from sane, modern compilers and not ancient compilers that tended to have bad error messages). While the language that they speak might be hard to decipher at times, they are not usually lying to you.
Let's look at it again:
The literal of int 9223372036854775807 is out of range.
Note, that it doesn't mention your variable testLong or the type long anywhere, so the problem is not about the initialization. It seems to occur at some other point.
Now lets investigate some of the parts of the message:
int tells us that he wants to treat something as an int value (which is not what you wanted!)
"out of range" is pretty clear: something is not within the expected range (probably that of int)
"The literal": now that's interesting: what is a literal?
I'll leave the cozy list to talk about literals for a moment: literals are places where you have some value in your code. There are String literals, int literals, class literals and so on. Every time you mention a value explicitly in your code, it's a literal.
So it's not actually nagging you about the variable declaration, but the number itself, the value is what it's nagging you about.
You can easily verify this by using the same literal in a context where a long and an int are equally acceptable:
System.out.println(9223372036854775807);
PrintStream.println can take either an int or a long (or pretty much anything else). So that code should be fine, right?
No. Well, maybe it should be, but according to the rules it is not fine.
The problem is that "some digits" is defined to be an int literal and therefore must be in the range defined by int.
If you want to write a long literal, then you must make that explicit by appending the L (or lower case l, but I highly suggest you always use the upper-case variant, because it's much easier to read and harder to mistake for a 1).
Note that a similar problem occurs with float (postfix F/f) and double (postfix D/d).
Side note: you'll realize that there are no byte or short literals and you can still assign values (usually int literals) to byte and short variables: that's possible due to special rules in § 5.2 about conversions in an Assignment Contexts: they allow assignment of constant expressions of a larger type to byte, short, char or int if the values are within the types range.
Try doing 9223372036854775807L. The L at the end tells Java that 9223372036854775807 is a long.
I had this problem in the past and I fixed that by writing the value in the scientific form.
for example:
double val = 9e300;
long ak = 34778754226788444L/l;
Both use but at a time only one use uppercase L or lowercase l.
Why use L/l? Because long is a part of integral datatype.
This question already has answers here:
Reasoning behind having to specify L for long, F,D for float, double
(3 answers)
Closed 8 years ago.
When I execute this code in java:
long l = 999_999_999_999;
I get the following error,
error: integer number too large: 999999999999
long l = 999_999_999_999;
But if I explicitly specify the number as long by adding l or L at the end, the problem disappears.
long l = 999_999_999_999L; // Works
My question is, why?
I know that all integral literals in java are integer by default, but why it would stop java from type casting and accommodating the value in a long, when a long is clearly large enough to hold the literal?
I am looking for some technical details.
This is perfectly intended.
Think about how the program is parsed. The lexer which splits the Java source into tokens knows about two things of literal:
the ones which don't end with [L|l]
the ones which end with [L|l]
A literal which doesn't have the long specifier at the end is parsed as an integer. This means that the literal itself is invalid because you are not allowed to define an integer literal which is larger than the larger number that you can represent with an int.
This is clear in the grammar specification here:
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).
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).
So even without any assignment, if you have the expression
999_999_999_999
This is parsed as an integer literal, but its value is over the maximum allowed value, hence it is illegal. The fact that the value of this expression is later assigned to something is irrelevant.
Java won't automatically cast your int literal as a long, because the int literal is invalid in the first place. That's why long literals exist, so values greater in magnitude can be expressed as literals.
According to the JLS, Section 3.10.1:
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).
In Java, you simply can't have an int literal bigger than Integer.MAX_VALUE, even if its only use is to assign a value to a long. Bigger literals must be long with an L suffix to begin with.
If your going to understand your problem. You will have to understand how Java reads and assign values to variables.
Java first reads the value that you want to assign to the variable, which is "99999999" then assigns it to the variable.
Without the "L" at the end, Java reads the value of the number, but encounters the problem that it is too big for an int. with the "L" at the end, Java knows it is a Long, therefore it is large enough.
So at the top of my code I declared the variable
private long counter;
And when I try to give it a number that's really long it gives an error, Im trying to do this
counter = 1111111111111111;
Thats 16 "1"s and I keep getting the error "The literal 1111111111111111 of type int is out of range" what am I doing wrong?
Try it like this:
counter = 1111111111111111l;
Note that the last character there is the letter 'L' (lowercase, of course), and not the number one. Here is a clearer example:
counter = 2222222222222222L;
As others have pointed out, an uppercase 'L' also works and is much more clear. All integer literals in Java are interpreted as ints unless you suffix them with an 'L' (or 'l') to tell the compiler to interpret it as a long.
A similar thing happens with literal floating-point numbers, which are interpreted as doubles by default unless you suffix them with an 'f' to tell the compiler to interpret it as a float. As in:
double num1 = 1.0; //1.0 is treated as a literal double
float num2 = 1.0; //1.0 is still treated as a literal double; the compiler may complain about loss of precision
float num3 = 1.0f; //1.0 is treated as a float, and the compiler is happy
The java compiler reads any number as an integer by default. 11111111111 is obviously outside the range of an integer. Type counter=11111111111L; to get the compiler to read the value correctly.
The problem is that numeric literals are ints by default. To make the numeric literal a long you have to finish it with the alpha character l (lower-case L). So:
long counter = 1111111111111111l;
In C# you can also use an upper-case L. I'm not sure about Java.
assertEquals( new Long(42681241600) , new Long(42681241600) );
I am try to check two long numbers but when i try to compile this i get
integer number too large: 42681241600
error. Documentation shows there is a Long,Long assertEquals method but it is not called.
You want:
assertEquals(42681241600L, 42681241600L);
Your code was calling assertEquals(Object, Object). You also needed to append the 'L' character at the end of your numbers, to tell the Java compiler that the number should be compiled as a long instead of an int.
42681241600 is interpreted as an int literal, which it is too large to be. Append an 'L' to make it a long literal.
If you want to get all technical, you can look up §3.10.1 of the JLS:
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 should also generally consider using Long.valueOf since this may allow some optimisation:
Long val = Long.valueOf(1234L);
From the J2SDK:
public static Long valueOf(long l)
Returns a Long instance representing
the specified long value. If a new
Long instance is not required, this
method should generally be used in
preference to the constructor
Long(long), as this method is likely
to yield significantly better space
and time performance by caching
frequently requested values.
append an "L" at the end of your number, like:
new Long(42681241600L)
in Java, every literal number is treated as an integer.