Java long byte length [duplicate] - java

This question already has answers here:
What is “two's complement”?
(24 answers)
Closed 4 years ago.
If Java's long primitive data type is a 64-bit signed integer, then why do the Java docs state that the static long maximum value is 2^63-1? Is there a larger reason that affects other primitive data types similarly in Java?
I'm learning Java and am just genuinely curious about this disparity. Thank you.

Java's long type is indeed a 64-bit integer, but it is also signed.
With 64-bit, you can represent 2^64 different numbers. If you ignore all the negative numbers, then the maximum value would be 2^64-1, and minimum will be 0. 0 plus all 2^64-1 positive numbers is 2^64 numbers in total.
However, if you consider all the negative numbers as well as the positives, about half of the 2^64 different numbers will be negative. Java just chose to represent 2^63 negative numbers, the number 0, and 2^63-1 positive numbers. If you add all these up, you get 2^64 total numbers.
2^63 + 1 + 2^63 - 1 = 2^64
^
|
this is the number zero

Its just a range formula just like range for octal and hexadecimal numbers 2^n -1
different for signed and unsigned numbers. 2^n and 2^n-1(Range)

Related

Why java int type has valid value in range -2,147,483,648 to 2,147,483,647? [duplicate]

This question already has answers here:
What is “two's complement”?
(24 answers)
Closed 3 years ago.
I'm wondering why java int type (32 bit signed) has valid value in range -2,147,483,648 to 2,147,483,647 but not in (-2,147,483,648 to 2,147,483,648)?
The primary representation of numbers in modern computers is some form of binary representation. It consists of a fixed number of bits that take the values 0 or 1. In Java, an int is specified to use a binary representation with 32 bits.
A 32 bit binary representation can have 2^32 states. (This is a mathematical fact. It can be proven from first principles.)
Consider the mathematical integers from -2^31 to +2^31:
There are 2^31 numbers in the range 1 to 2^31 (inclusive)
There are 2^31 numbers in the range -1 down to -(2^31) (inclusive)
The value zero is not in either of the above ranges.
So counting the numbers from -2^31 to +2^31, we get a total of 2^31 + 2^31 + 1 values. That is 2^32 + 1 which is more values than can be represented in 2^32 states.
What you are suggesting is not mathematically possible.

Why is 2,147,483,647 the max int value?

Can someone provide me with a detailed explanation of why 2,147,483,647 is the maximum integer value in Java?
Because the total value an int can hold in Java is 2^32 (2 to the power of 32, in other words a 32 bit number), for which half is reserved for negative numbers and half for positive numbers.

Assign negative int to long in java

I've 2 integer values stored in a bytebuffer, in little-endian format. These integers are actually the 32-bit pieces of a long. I've to store them as a class' member variables, loBits and hiBits.
This is what I did:
long loBits = buffer.getInt(offset);
long hiBits = buffer.getInt(offset + Integer.BYTES);
I want to know why directly assigning signed int to long is wrong. I kind of know what's going on, but would really appreciate an explanation.
The int I read from the buffer is signed (because Java). If it is negative then directly assigning it to a long value (or casting it like (long)) would change all the higher order bits in the long to the signed bit value.
For e.g. Hex representation of an int, -1684168480 is 9b9da0e0. If I assign this int to a long, all higher order 32 bits would become F.
int negativeIntValue = -1684168480;
long val1 = negativeIntValue;
long val2 = (long) negativeIntValue;
Hex representation of:
negativeIntValue is 0x9b9da0e0
val1 is 0xffffffff9b9da0e0
val2 is 0xffffffff9b9da0e0
However, if I mask the negativeIntValue with 0x00000000FFFFFFFFL, I get a long which has the same hex representation as negativeIntValue and a positive long value of 2610798816.
So my questions are:
Is my understanding correct?
Why does this happen?
Yes, your understanding is correct (at least if I understood your understanding correctly).
The reason this happens is because (most) computers use 2's complement to store signed values. So when assigning a smaller datatype to a larger one, the value is sign extended meaning that the excess part of the datatype is filled with 0 or 1 bits depending on whether the original value was positive or negative.
Also related is the difference between >> and >>> operators in Java. The first one performs sign extending (keeping negative values negative) the second one does not (shifting a negative value makes it positive).
The reason for this is that negative values are stored as two's complement.
Why do we use two's complement?
In a fixed width numbering system what happens, if you substract 1 from 0?
0000b - 0001b -> 1111b
and what is the next lesser number to 0? It is -1.
Therfore we thread a binary number with all bits set (for a signed datatype) as -1
The big advantage is that the CPU does not need to do any special operation when changing from positive to negative numbers. It handles 5 - 3 the same as 3 - 5

Why is the maximum capacity of a Java HashMap 1<<30 and not 1<<31?

Why is the maximum capacity of a Java HashMap 1<<30 and not 1<<31, even though the max value of an int is 231-1? The maximum capacity is initialized as static final int MAXIMUM_CAPACITY = 1 << 30;
Java uses signed integers which means the first bit is used to store the sign of the number (positive/negative).
A four byte integer has 32 bits in which the numerical portion may only span 31 bits due to the signing bit. This limits the range of the number to 2^31 - 1 (due to inclusion of 0) to - (2^31).
While it would be possible for a hash map to handle quantities of items between 2^30 and 2^31-1 without having to use larger integer types, writing code which works correctly even near the upper limits of a language's integer types is difficult. Further, in a language which treats integers as an abstract algebraic ring that "wraps" on overflow, rather than as numbers which should either yield numerically-correct results or throw exceptions when they cannot do so, it may be hard to ensure that there aren't any cases where overflows would cause invalid operations to go undetected.
Specifying an upper limit of 2^30 or even 2^29, and ensuring correct behavior on things no larger than that, is often much easier than trying to ensure correct behavior all the way up to 2^31-1. Absent a particular reason to squeeze out every last bit of range, it's generally better to use the simpler approach.
By default, the int data type is a 32-bit signed two's complement integer, which has a minimum value of -2^31 and a maximum value of (2^31)-1, ranges from –2,147,483,648 to 2,147,483,647.
The first bit is reserved for the sign bit — it is 1 if the number is negative and 0 if it is positive.
1 << 30 is equal to 1,073,741,824
it's two's complement binary integer is 01000000-00000000-00000000-00000000.
1 << 31 is equal to -2,147,483,648.
it's two's complement binary integer is 10000000-00000000-00000000-00000000.
It says the maximum size to which hash-map can expand is 1,073,741,824 = 2^30.
You are thinking of unsigned, with signed upper range is (2^31)-1

Why do integers in Java integer not use all the 32 or 64 bits?

I was looking into 32-bit and 64-bit. I noticed that the range of integer values that can stored in 32 bits is ±4,294,967,295 but the Java int is also 32-bit (If I am not mistaken) and it stores values up to ±2 147 483 648. Same thing for long, it stores values from 0 to ±2^63 but 64-bit stores ±2^64 values. How come these values are different?
Integers in Java are signed, so one bit is reserved to represent whether the number is positive or negative. The representation is called "two's complement notation." With this approach, the maximum positive value represented by n bits is given by
(2 ^ (n - 1)) - 1
and the corresponding minimum negative value is given by
-(2 ^ (n - 1))
The "off-by-one" aspect to the positive and negative bounds is due to zero. Zero takes up a slot, leaving an even number of negative numbers and an odd number of positive numbers. If you picture the represented values as marks on a circle—like hours on a clock face—you'll see that zero belongs more to the positive range than the negative range. In other words, if you count zero as sort of positive, you'll find more symmetry in the positive and negative value ranges.
To learn this representation, start small. Take, say, three bits and write out all the numbers that can be represented:
0
1
2
3
-4
-3
-2
-1
Can you write the three-bit sequence that defines each of those numbers? Once you understand how to do that, try it with one more bit. From there, you imagine how it extends up to 32 or 64 bits.
That sequence forms a "wheel," where each is formed by adding one to the previous, with noted wraparound from 3 to -4. That wraparound effect (which can also occur with subtraction) is called "modulo arithemetic."
In 32 bit you can store 2^32 values. If you call these values 0 to 4294967295 or -2147483648 to +2147483647 is up to you. This difference is called "signed type" versus "unsigned type". The language Java supports only signed types for int. Other languages have different types for an unsigned 32bit type.
NO laguage will have a 32bit type for ±4294967295, because the "-" part would require another bit.
That's because Java ints are signed, so you need one bit for the sign.

Categories