logo

Java - Numbers

Last Updated: 2021-11-19

Max Value and Min Value

Unlike C/C++, Java only has signed numbers. Integer in Java ranges from -2147483648 to 2147483647, note that there's 1 more negative number than the positive numbers, because 0 also has the "positive" sign(highest bit is 0).

jshell> Integer.MAX_VALUE
$1 ==> 2147483647

jshell> Integer.MIN_VALUE
$2 ==> -2147483648

The extra negative number means that there's no absolute value of the MIN_VALUE:

jshell> Math.abs(Integer.MIN_VALUE)
$3 ==> -2147483648

It is still negative. To get the correct value, you can convert it to long before taking the absolute value, so that the 32 bit will be freed up from being the sign:

jshell> Math.abs((long)Integer.MIN_VALUE)
$4 ==> 2147483648

Another confusing thing: if you step one step further from the MIN_VALUE, you are back to MAX_VALUE

jshell> Integer.MIN_VALUE - 1
$5 ==> 2147483647

What is MAX + MAX?

jshell> Double.MAX_VALUE
$6 ==> 1.7976931348623157E308

jshell> Double.MAX_VALUE + Double.MAX_VALUE
$7 ==> Infinity

Bit Manipulation

An example: how to create an arbitrary bit string like 11111111111111111111111111000111

All 1: ~0 will give you all 1, by negating every single bit:

jshell> Integer.toBinaryString(~0)
$1 ==> "11111111111111111111111111111111"

Shift

jshell> Integer.toBinaryString(~0 << 6)
$2 ==> "11111111111111111111111111000000"

Get some 1s

jshell> Integer.toBinaryString(1 << 3)
$3 ==> "1000"

jshell> Integer.toBinaryString((1 << 3) - 1)
$4 ==> "111"

Combine the 2 parts:

jshell> Integer.toBinaryString((~0 << 6) | ((1 << 3) - 1))
$5 ==> "11111111111111111111111111000111"

Another example with Long:

jshell> Long.toBinaryString((~0L << 32) | ((1L << 31) - 1))
$6 ==> "1111111111111111111111111111111101111111111111111111111111111111"

Binary Literals

Add the prefix 0b or 0B to the number

// An 8-bit 'byte' value:
byte aByte = (byte)0b00100001;

// A 16-bit 'short' value:
short aShort = (short)0b1010000101000101;

// Some 32-bit 'int' values:
int anInt1 = 0b10100001010001011010000101000101;
int anInt2 = 0b101;
int anInt3 = 0B101; // The B can be upper or lower case.

// A 64-bit 'long' value. Note the "L" suffix:
long aLong = 0b1010000101000101101000010100010110100001010001011010000101000101L;

Underscores in Numeric Literals

long creditCardNumber = 1234_5678_9012_3456L;
long socialSecurityNumber = 999_99_9999L;

parseDouble vs valueOf

  • Double.parseDouble(String s) returns double (the primitive)
  • Double.valueOf(String s) returns Double (the object)

Some tests

jshell> Double.valueOf("Infinity")
$1 ==> Infinity

jshell> Double.valueOf("-Infinity").isInfinite()
$2 ==> true

jshell> Double.valueOf("NaN")
$3 ==> NaN

Hex

Imaging a concatenated string using 0x7f as delimiter, we could split it in two easy ways:

char delimiter = 0x7f;
String [] vals = line.split(Character.toString(delimiter));

or simply:

String [] vals = line.split("\\x7f");

However it is a different story to join them. It is ok like this:

String s = "";
for (String v : vals) {
    s += v + delimiter;
}

but if use

s += v + "\\x7f";

it will add 4 character after each v: , x, 7, f, instead of a hex 0x7f, and hence could not split it again as we discussed above.

Number Format

DecimalFormat df = newDecimalFormat("#.##");
System.out.print(df.format(d));