Java Tutorial
🔍

Java Number Systems: Binary, Octal and Hex

Java Number Systems

Every number in a Java program is stored as binary — ones and zeros — but you can write and display it in four different bases: decimal (base 10), binary (base 2), octal (base 8) and hexadecimal (base 16). Knowing how these bases relate explains bitwise operators, colour codes, file permissions, memory addresses, and why int x = 010; is not ten.

What Is a Number System?

A number system (or base) decides how many different digits are available and what each position is worth. In base 10 there are ten digits, 0 to 9, and each position is worth ten times the one to its right: 345 means 3 × 100 + 4 × 10 + 5 × 1.

The same idea works for any base. Only the number of digits and the value of each position change.

SystemBaseDigitsPosition values (right to left)Java literal prefix
Binary20–11, 2, 4, 8, 16, …0b or 0B
Octal80–71, 8, 64, 512, …0 (a leading zero)
Decimal100–91, 10, 100, 1000, …none
Hexadecimal160–9, A–F1, 16, 256, 4096, …0x or 0X

In hexadecimal, the letters A to F stand for the values 10 to 15, because base 16 needs sixteen single-character digits.

Writing Numbers in Different Bases in Java

Java lets you write an integer literal in any of the four bases. All of them produce exactly the same int value in memory — the base only affects how you type it.

1public class NumberLiterals { 2 public static void main(String[] args) { 3 int decimal = 42; 4 int binary = 0b101010; // 32 + 8 + 2 5 int octal = 052; // 5 × 8 + 2 6 int hex = 0x2A; // 2 × 16 + 10 7 8 System.out.println(decimal + " " + binary + " " + octal + " " + hex); 9 10 int mask = 0b1111_0000; // underscores group digits for readability 11 long card = 1234_5678_9012_3456L; 12 System.out.println(mask + " " + card); 13 } 14}

Output:

42 42 42 42 240 1234567890123456

Underscores between digits (Java 7 and later) are ignored by the compiler. They're especially useful in binary literals, where long runs of ones and zeros are hard to read.

Converting Between Bases by Hand

Decimal to Another Base: Divide and Collect Remainders

Divide the number by the target base, write down the remainder, and repeat with the quotient until it reaches 0. Reading the remainders from last to first gives the digits.

Converting 45 to binary:

StepDivisionQuotientRemainder
145 ÷ 2221
222 ÷ 2110
311 ÷ 251
45 ÷ 221
52 ÷ 210
61 ÷ 201

Reading the remainders bottom-up gives 101101.

Another Base to Decimal: Multiply by Position Values

Multiply each digit by its position value and add the results. For binary 101101:

1 × 32 + 0 × 16 + 1 × 8 + 1 × 4 + 0 × 2 + 1 × 1 = 45

A faster way to do the same thing in code is to read the digits from left to right and keep a running total: multiply the total by the base, then add the next digit. For 101101 the total goes 1, 2, 5, 11, 22, 45.

Binary to Octal and Hex: Group the Bits

Because 8 = 2³ and 16 = 2⁴, each octal digit is exactly 3 bits and each hex digit is exactly 4 bits. Group the binary digits from the right:

  • ›Octal: 101 101 → 5 5 → 55
  • ›Hex: 0010 1101 → 2 D → 2D

That direct mapping is why programmers use hex as a compact way to read binary data.

Converting Between Bases with Java Methods

The Integer class (and Long, for 64-bit values) has methods for every common conversion.

1public class BaseConversions { 2 public static void main(String[] args) { 3 int n = 45; 4 5 // decimal -> other bases (returns a String) 6 System.out.println(Integer.toBinaryString(n)); // 101101 7 System.out.println(Integer.toOctalString(n)); // 55 8 System.out.println(Integer.toHexString(n)); // 2d 9 System.out.println(Integer.toString(n, 3)); // any radix from 2 to 36 10 11 // other bases -> decimal (returns an int) 12 System.out.println(Integer.parseInt("101101", 2)); 13 System.out.println(Integer.parseInt("55", 8)); 14 System.out.println(Integer.parseInt("2D", 16)); 15 System.out.println(Integer.decode("0x2D")); // understands 0x, # and 0 prefixes 16 } 17}

Output:

101101 55 2d 1200 45 45 45 45

Integer.toHexString prints lowercase letters. Use .toUpperCase() or String.format("%X", n) when you need uppercase, and String.format("%08X", n) to pad with zeros to a fixed width.

How Negative Numbers Are Stored: Two's Complement

Java's int is a 32-bit signed number stored in two's complement. To get the bit pattern of a negative number, take the positive value's bits, flip every bit, and add 1. The leftmost bit then acts as the sign: 0 for positive, 1 for negative.

1public class TwosComplement { 2 public static void main(String[] args) { 3 System.out.println(Integer.toBinaryString(5)); 4 System.out.println(Integer.toBinaryString(-5)); 5 System.out.println(Integer.toString(-5, 2)); // keeps the minus sign instead 6 System.out.println(Integer.MAX_VALUE + 1); // wraps around to the minimum 7 } 8}

Output:

101 11111111111111111111111111111011 -101 -2147483648

Two's complement is why Integer.MAX_VALUE + 1 silently becomes Integer.MIN_VALUE — adding 1 to 0111…1 produces 1000…0, which is the most negative 32-bit value.

Where You'll Meet Other Bases in Real Code

  • ›Hexadecimal — colour codes (#FF8800), byte dumps, hash values, memory addresses and Unicode escapes such as 'é'.
  • ›Binary — bit flags and masks, used with the bitwise operators &, |, ^ and <<.
  • ›Octal — Unix file permissions such as chmod 755, where each digit packs read, write and execute bits.

Common Mistakes

Mistake 1 — A Leading Zero Makes a Literal Octal

1int day = 09; // does not compile: 9 is not an octal digit 2int code = 010; // compiles, but the value is 8, not 10

Never pad integer literals with zeros for alignment. If you need a fixed-width display, format the output instead: String.format("%02d", day).

Mistake 2 — Parsing a Value Too Large for int

Integer.parseInt("11111111111111111111111111111111", 2) throws NumberFormatException, because that bit pattern is larger than Integer.MAX_VALUE as an unsigned number. Use Integer.parseUnsignedInt(text, 2) or Long.parseLong(text, 2) for full 32-bit patterns.

Mistake 3 — Expecting toBinaryString to Show a Minus Sign

toBinaryString, toOctalString and toHexString treat the value as unsigned and show the raw two's complement bits. Use Integer.toString(value, radix) when you want a human-readable result with a minus sign.

Interview Questions

How do you convert a decimal number to binary without built-in methods?

Repeatedly divide by 2, collect each remainder, and reverse the collected digits at the end. The full program, along with octal and hexadecimal versions, is in the practice programs below.

Why is hexadecimal so common in programming?

Each hex digit represents exactly four bits, so a byte is always two hex digits. That makes long binary values short and readable while still mapping directly to the underlying bits.

What is the output of System.out.println(010 + 0x10)?

  1. ›010 is octal 8 and 0x10 is hexadecimal 16.

What range of values can a Java int hold?

From −2,147,483,648 to 2,147,483,647, that is −2³¹ to 2³¹ − 1. The range is asymmetric because zero takes one of the non-negative bit patterns.

FAQs

Does Java have a binary data type?

No. Every integer type (byte, short, int, long) is already stored in binary. Binary, octal and hex are only different ways of writing or displaying the same value.

Can floating-point numbers be written in hexadecimal?

Yes, Java supports hexadecimal floating-point literals such as 0x1.8p1 (which is 3.0), but they're rare outside low-level numeric code.

What does the radix parameter mean?

Radix is another word for base. Integer.parseInt("ff", 16) reads the text as base 16, and Integer.toString(255, 2) writes the value in base 2. Java accepts any radix from 2 to 36.

Summary

A number system defines the digits available and the value of each position; decimal, binary, octal and hexadecimal are just different ways of writing the same stored value. Java lets you write literals in each base with no prefix, 0b, a leading 0, or 0x, and the Integer and Long classes convert between bases in both directions. Negative integers are stored in two's complement, which explains the long bit strings from toBinaryString and the wrap-around at Integer.MAX_VALUE.

What to Read Next

Practice Programs

Put this topic into practice — each program has full code, output and a step-by-step explanation you can run online.

Browse all Java programs →