"... I have a Java programt o display the limits of primitive integer datatypes ..."
You have a miscalculation.
If x is 2 × 10 n−1 − 1, you should not expect a negative value, and rather, 1 subtracted from the product.
You most-likely meant, −2, or, multiplied by −1.
In other words, the values would be, 128 and 127, and then, 32,768 and 32,767, etc.
And not, the minimum and maximum values, −128 and 127, −32,768 and 32,767, etc.
Nevertheless, the values would not be correct; as, your bounds are met.
Doing so will produce a set of bits that cannot be correctly expressed.
Wikipedia – Signed number representations – Two's complement.
Wikipedia – Integer_overflow.
If the MSb is reserved for a signum, then the printed value would not be a valid representation.
Here is a list of, x + n.
x bits
----------------
124 01111100
125 01111101
126 01111110
127 01111111
-128 10000000
-127 10000001
-126 10000010
-125 10000011
-124 10000100
-123 10000101
-122 10000110
-128
-128
-32768
-32768
2147483647
-2147483648
9223372036854775807
-9223372036854775808
Here is an example, to provide a comparison.
The first row, for each, is the unadulterated, double value; the result of
Math#pow.
The second row, is the result after the cast, of this value.
And finally, the third row, is the minimum, and maximum value, from the corresponding wrapper class.
type x | min y | max
--------------------------------------------------
byte 127 128
127 -128
-128 127
short 32767 32768
32767 -32768
-32768 32767
int 2147483647 2147483648
2147483647 2147483647
-2147483648 2147483647
long 9223372036854776000 9223372036854776000
9223372036854775807 9223372036854775807
-9223372036854775808 9223372036854775807
Here is the code.
public static void main(String[] args) {
Value[] a = {
new Value(byte.class),
new Value(short.class),
new Value(int.class),
new Value(long.class)
};
System.out.printf("%6s %20s %20s%n", "type", "x | min", "y | max");
System.out.println("-".repeat(50));
for (Value v : a) {
System.out.println(v);
System.out.printf("%48s%n", v.cast());
System.out.printf("%48s%n", v.bounds());
}
}
static class Value {
Class<?> t;
double x, y;
Value(Class<?> t) {
this.t = t;
int b = 0;
if (t == byte.class) b = 8;
else if (t == short.class) b = 16;
else if (t == int.class) b = 32;
else if (t == long.class) b = 64;
x = (y = Math.pow(2, --b)) - 1;
}
String cast() {
if (t == byte.class)
return "%20s %20s".formatted((byte) x, (byte) y);
else if (t == short.class)
return "%20s %20s".formatted((short) x, (short) y);
else if (t == int.class)
return "%20s %20s".formatted((int) x, (int) y);
else
return "%20s %20s".formatted((long) x, (long) y);
}
String bounds() {
if (t == byte.class)
return "%20s %20s".formatted(Byte.MIN_VALUE, Byte.MAX_VALUE);
else if (t == short.class)
return "%20s %20s".formatted(Short.MIN_VALUE, Short.MAX_VALUE);
else if (t == int.class)
return "%20s %20s".formatted(Integer.MIN_VALUE, Integer.MAX_VALUE);
else
return "%20s %20s".formatted(Long.MIN_VALUE, Long.MAX_VALUE);
}
@Override
public String toString() {
return "%6s %20.0f %20.0f".formatted(t.getSimpleName(), x, y);
}
}
Math.pow()returnsdouble, which can’t hold all the bits oflong. Use shifts.staticfields for the limits of the primitives. For integer primitives, you can useMAX_VALUEandMIN_VALUE. For example,Short.MIN_VALUE.