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.
Related
This question already has answers here:
Why is the default type of Java integer literals int instead of long? [closed]
(7 answers)
Closed 6 months ago.
I know that max value for int and long are very high but somehow I am not able to handle them in my code. I am getting compilation error in all the scenarios below. Could someone please suggest how I can handle 20118998631 value.
I know that if I put l after this value 20118998631l then declaring it as long will work but problem is that I am getting this from a network call and if I declare my field as long and value will come simply as 20118998631 then it will break.
int x = 20118998631; // compilation error
long l = 20118998631; // compilation error
double d = 20118998631; // compilation error
Long l1 = new Long(20118998631); // compilation error
I know that max value for int and long are very high
The definition of 'very' is in the eye of the beholder, isn't it?
The max value of an int is Integer.MAX_VALUE, which is 2147483647. Specifically, that's 2, to the 31st power, minus 1. Because computers use bits, int uses 32 bits, and about half of all the numbers an int can represent are used to represent negative numbers, hence why you end up with 2^31-1 as max int.
For longs, its 2^63-1 for the same reason: long uses 64 bit, and half of all representable values are negative.
If you have numbers that are larger than this, you need to use BigInteger (a class in the standard library for integers of arbitrary size) or byte[] or something else.
but problem is that I am getting this from a network call and if I declare my field as long and value will come simply as 20118998631 then it will break.
This doesn't make sense. Are you getting stuff from the network, shoving what you get into a file with a prefix and suffix, and then that file is something you compile with javac? That sounds bonkers, but if you are, just.. add that L. Or, add " before and after the number and pass that to new BigInteger instead, now the number can be thousands of digits large if you want it to be.
Otherwise, you're getting a bytes which either represent the number directly (and the L aspect is not relevant to this conversation), or you're getting a string in, which again, isn't relevant to this conversation: That L is just for writing literal numbers inside .java files, it doesn't come up anywhere else. Turning a string containing digits, such as "20118998631" into e.g. a long is done with Long.parseLong("20118998631") which works fine, and does not require the L (in fact, it won't work if you include it).
As people have already mentioned in the comments, we need more details about your networking in order to answer the question in full.
In general:
Your respons will be in form of a string (or byte array to be exact) and you will have to convert this to your representation.
You will have to use a function to convert the string to your desired representation, for example, Long.valueOf("20118998631") would do it.
But depending on the setup in use you might need to configure your networking to interpret the incoming number as long.
In general, most developers tend to use int for most things, so you might have code in your networking that tries to convert all numbers to int, which will not work with numbers larger than 2147483647, no matter what. The StackTrace should help in this case.
For the examples provided in your question:
int x = 20118998631;
/*
compilation error, the number doesn't fit within an integer and never will.
Therefore expected.
*/
long l = 20118998631;
/*
compilation error, you assign to the variable l the integer constant 20118998631;
this will not work as the given integer is larger than max int.
Use 20118998631L (not the L) to use a long
*/
double d = 20118998631;
/*
compilation error, same as with long above, use a capital D to interpret the number as double
*/
Long l1 = new Long(20118998631);
/*
compilation error
Same as with long above, you declare an integer constant larger than max int and box it within long.
Add a trailing L for long and preferably remove the boxing (java will auto-box if necessary)
*/
So 20118998631L = 0x4_AF2F_8E67L which does not fit in a java int of 4 bytes, only in a long.
The REST API defines an INT and indeed in an SQL INT this might fit.
Getting the "INT" as String s you must do Long.parseLong(s).
Getting the "INT" as bytes, then 04 might be a size (4 bytes), of 2939129447.
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.
To create a new Integer object that holds the value in java 1 which one of the following is right and what exactly is the difference in the following methods as all print the value?
Method 1 :
Integer p = new Integer(1);
Method 2 :
Integer p = 1;
Method 3 :
Integer p = new Integer("1");
Using method three I got the following warning :
Note: HelloWorld.java uses or overrides a deprecated API.
Note: Recompile with -Xlint:deprecation for details
You skipped the intended solution:
Integer p = Integer.valueOf(1);
This pattern is known as Factory method pattern. One may ask what the benefit of this method is. Luckily, the implementation of class Integer is open-source, so let's take a look:
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
There seems to be some kind of Integer-value cache. If one requests an Integer with a value within the cache-range, Java does not create a new object, but returns a previously created one. This works because Integers are immutable. One can even control the upper cache limit with the system property java.lang.Integer.IntegerCache.high=....
And why do the other two methods of creating an Integer generate a warning? Because they were set deprecated with Java 9.
Integer#Integer(int value):
Deprecated. It is rarely appropriate to use this constructor. The static factory valueOf(int) is generally a better choice, as it is likely to yield significantly better space and time performance. [...]
Integer#Integer(String s):
Deprecated. It is rarely appropriate to use this constructor. Use parseInt(String) to convert a string to a int primitive, or use valueOf(String) to convert a string to an Integer object. [...]
And just for completeness, here is the part for Integer.valueOf(int i):
Returns an Integer instance representing the specified int value. If a new Integer instance is not required, this method should generally be used in preference to the constructor Integer(int), as this method is likely to yield significantly better space and time performance by caching frequently requested values. This method will always cache values in the range -128 to 127, inclusive, and may cache other values outside of this range.
EDIT 1: Thanks to #VGR mentioning that
Integer p = 1;
is equivilant to
Integer p = Integer.valueOf(1);
This, however, is only true for int-values between -128 and 127. The behaviour is defined in JLS §5.1.7:
[...] If the value p being boxed is the result of evaluating a constant expression (§15.28) of type boolean, char, short, int, or long, and the result is true, false, a character in the range '\u0000' to '\u007f' inclusive, or an integer in the range -128 to 127 inclusive, then let a and b be the results of any two boxing conversions of p. It is always the case that a == b.
EDIT 2: Thanks to #DorianGray, who brought the following to my attention.
While not in the JLS, the version of javac I am using (9.0.4) does compile the boxing down to Integer.valueOf(...); as it is shown in this answer by Adam Rosenfield.
Method 4, Integer p = Integer.valueOf(1); is the recommended way. The JavaDoc says:
Returns an Integer instance representing the specified int value. If a
new Integer instance is not required, this method should generally be
used in preference to the constructor Integer(int), as this method is
likely to yield significantly better space and time performance by
caching frequently requested values. This method will always cache
values in the range -128 to 127, inclusive, and may cache other values
outside of this range.
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.
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).)