Integer range when using 64bit jdk - java

As I understand the difference between two integer from 32bit & 64bit are the following:
32bit range −2,147,483,648 to 2,147,483,647
64bit range: −9,223,372,036,854,775,808 to +9,223,372,036,854,775,807
I am using a 64bit jdk, I validate it by printing the following:
System.out.println("JVM Bit size: " + System.getProperty("sun.arch.data.model"));
JVM Bit size: 64
when I try to init a new Integer variable with number bigger ther 10 letters I get a compilation error. why is that? it looks like the 64bit is larger
example (ran on netbeans):
int x = 12345678910; => Error: integer is too large

The size of an int in Java is completely independent of the 32-bitness or 64-bitness of a JDK. It is always 4 bytes = 32 bits = −2,147,483,648 to 2,147,483,647.
If you want a 64-bit integer, use a long, which is always 64 bits = 8 bytes.

Unlike other languages, Java's numeric primitive types are always the same size, whatever the platform (32bit or 64bit, LE or BE); they are all big endian and are 1 byte long for byte, 2 bytes long for short and char, 4 bytes long for int and 8 bytes long for long.
If it were not the case, jars would not be portable across platforms...

Your best resource is JLS:
The integral types are byte, short, int, and long, whose values are 8-bit, 16-bit, 32-bit and 64-bit signed two's-complement integers, respectively, and char, whose values are 16-bit unsigned integers representing UTF-16 code units
4.2.1. Integral Types and Values
The values of the integral types are integers in the following ranges:
For byte, from -128 to 127, inclusive
For short, from -32768 to 32767, inclusive
For int, from -2147483648 to 2147483647, inclusive
For long, from -9223372036854775808 to 9223372036854775807, inclusive
For char, from '\u0000' to '\uffff' inclusive, that is, from 0 to 65535

Related

How to calculate the value of any primitive , who has out of range value

Example
byte x;
x=(byte)2355;
System.out.println(x);
so, how can I calculate the value which will be in x;
The 2355 literal value is interpreted as an int, which in Java is represented by the following 32 bits:
00000000000000000000100100110011
A byte has only 8 bits, so you lose the leading 24 bits:
00110011
Converted back to decimal, this leaves you with a value of 51.
You can find the bit sizes of the various primitive data types here. Also keep in mind that you need to take two's complement into account when dealing with signed primitives.
The range of the byte data type is -128 to 127 (inclusive). So if you want to deal with numbers outside that range then you can try casting the data type to short, int or long.

How much byte a long variable takes if int value is stored in it?

I am storing an integer value in long variable ut if I am giving value greater than int range then it is saying that "literal of type int is greater than range".
The range of integer is 2147483648 to 2147483647
So when I am storing
long l=2147483647;
then it is running fine
But when I am storing
long l=2147483648;
then it is giving compile time error as "literal of type int is greater than range"
So I want to know that if I am storing long l=2147483647;
i.e. value of int range in long variable then does it uses 32 bit or 64 bit to store it.
Also if it uses 64 bit then why it is giving error for long l=2147483648;
You seem to think that when a long stores a value that is within the range of int, it will use 32 bits to store it. This is not true.
Java Language Specification Section 4.2 Primitive Types and Values
The integral types are byte, short, int, and long, whose values are 8-bit, 16-bit, 32-bit and 64-bit signed two's-complement integers, respectively.
You got the compiler error because the integer literal 2147483648 cannot be used in that context. The error has nothing to do with the size of long.
Section 3.10
All decimal literals from 0 to 2147483647 may appear anywhere an int
literal may appear. The decimal literal 2147483648 may appear only as
the operand of the unary minus operator - (§15.15.4).
It is a compile-time error if the decimal literal 2147483648 appears
anywhere other than as the operand of the unary minus operator; or if
a decimal literal of type int is larger than 2147483648

How does overflow work in java?

I've read about overflow, I know that "Overflow is when a number is so large that it will no longer fit within the data type, so the system “wraps around” to the next lowest value and counts up from there".
For example:
short s = (short)1921222; // Stored as 20678
In that example we started counting from -32768 (Short.MIN_VALUE), but when I try to prove in another integer data types, it doesn't seem work the same way...
byte b = (byte)400; // Stored as -112
The example above started counting from 0 that was the only way I found to get -112
I don't know if I am doing something wrong.
The Java Language Specification says:
The integral types are byte, short, int, and long, whose values are 8-bit, 16-bit, 32-bit and 64-bit signed two's-complement integers, respectively, and char, whose values are 16-bit unsigned integers representing UTF-16 code units.
So, short and byte are both two's complement integers.
short is 16 bits, meaning it can hold 2^16 = 65536 different values. After the 65536th value, it overflows.
1921222 modulo 65536 is 20678 . This is less than 32768 (2^15, the turning point for the two's complement) so we keep a positive number.
byte is 8 bits, meaning it can hold 2^8 = 256 different values. This one overflows after the 256hth value.
400 modulo 256 is 144. This value is higher than 128, the turning point for the two's complement - hence it will be interpreted as a negative two's complement number.
The cast is truncating the number. (JLS)
0000 0001 1001 0000
loses the high byte to become
1001 0000
which is -112.
In java, byte primitive type is an 8 bit signed integer, that's why you got -112 from calling:
byte b = (byte) 400;
You can avoid that and get its un-signed value, by binary adding it with 0xFF like this:
int b = (byte) 400 & 0xFF;
For further details you can check:
Java Primitive data types Documentation.
How to Convert Int to Unsigned Byte and Back
In addition to the other answers, you can get to that answer by manual calculation as well.
In Java, the data type byte is an 8-bit, signed integer. So the values are in the interval [-128, 127]. If you have a value of 400 and you want to see the actual value for that type, you can subtract the size of the interval from that number until you reach a value that's inside the interval.
As I said, byte is 8 bit, so the size of the interval is 256. Subtract that from your initial value: 400 - 256 = 144. This value is still outside of the interval so you have to subtract again: 144 - 256 = -112. This value is now inside the interval and is indeed the value you've seen in your test.
The same is true for your first example: short is 16 bit and signed, so the interval is [-32768, 32767] with size 65536. Doing repeated subtraction from the value 1921222 will eventually give you the value 20678 as seen in your test.

Will an int be 32bit and a long 64bit regardless of whether the system is 32 or 64 bit?

In java, is an int guaranteed to always be of 32bit size and a long of 64bit size regardless of whether the architecture is 32 or 64 bit?
Java is platform independent. So int is 32-bits, and long is 64-bit.
int in Java is always 32-bit. No matter the OS type/architecture/whatever.
The Java Tutorial page on primitive data types specifies the fixed sizes and makes no mention of underlying architecture having any influence
int: The int data type is a 32-bit signed two's complement integer. It has a minimum value of -2,147,483,648 and a maximum value of 2,147,483,647 (inclusive).
long: The long data type is a 64-bit signed two's complement integer.
It has a minimum value of -9,223,372,036,854,775,808 and a maximum
value of 9,223,372,036,854,775,807 (inclusive). Use this data type
when you need a range of values wider than those provided by int.

Does Java bitwise representation of long vary?

I would like to fill a Java array of longs, so that all of its bits are set to 1. I've found out that the corresponding long value is -1, or "0xFFFFFFFFFFFFFFFFl":
long l = -1L;
System.out.println(Long.toBinaryString(l));
"1111111111111111111111111111111111111111111111111111111111111111"
So I use Arrays.fill() to fill the array with 1's:
final long allBitsOn = -1L;
long[] bits = new long[arrayLength];
Arrays.fill(bits, allBitsOn);
This array is a fundamental infrastructure of a major project, and I want to be completely sure that long has 64 bits, and that long(-1) will always have all its bits set to 1, across all VM implementations and future versions of Java.
Is this assumption safe?
Yes, the assumption is safe. From the JLS:
4.2. Primitive Types and Values
The integral types are byte, short, int, and long, whose values are 8-bit, 16-bit, 32-bit and 64-bit signed two's-complement integers, respectively, and char, whose values are 16-bit unsigned integers representing UTF-16 code units (§3.1).
In two's complement, -1 is represented by the bit pattern consisting of all ones.
Is this assumption safe?
Yes, it's defined by the Java Language Specification, Section 4.2:
The integral types are byte, short, int, and long, whose values are 8-bit, 16-bit, 32-bit and 64-bit signed two's-complement integers, respectively...
What you describe is how two's complement integer numbers work, -1 is "all bits on".

Categories