Number Systems: Binary, Hexadecimal, Decimal & Bit Operations
This post is a comprehensive introduction to number systems – covering binary, hexadecimal, decimal, base conversion, and bit operations with practical examples.
In a Nutshell
Computers use binary systems (0 and 1). Hexadecimal serves as a compact representation for binary values. Bit operations enable direct manipulation of data at the bit level.
Learning Path
Beginner (Steps 1-3):
- Understand number system fundamentals (decimal, binary, hexadecimal)
- Practice simple conversions (decimal ↔ binary ↔ hex)
- Learn basic bit operations (AND, OR, XOR)
Intermediate (Steps 4-6): 4. Understand two’s complement and negative numbers 5. Practical applications (IP addresses, colors, MAC addresses) 6. Shift operations and bit manipulation
Advanced (Steps 7-10): 7. Advanced topics (BCD, Gray code, CRC) 8. IEEE 754 floating-point format 9. Endianness and network byte order 10. Performance optimization with bit operations
💡 Pro-Tip: Start with the interactive exercises to test your understanding!
Quick Technical Overview
Number systems are methods for representing numbers using different bases. Computers internally use the binary system (base 2), while humans prefer the decimal system (base 10).
Key number systems:
Decimal System (Base 10)
- Digits: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
- Place values: 10⁰, 10¹, 10², 10³, …
- Usage: Human communication, everyday mathematics
- Example: 123 = 1×10² + 2×10¹ + 3×10⁰
Visual representation:
1 2 3
↓ ↓ ↓
10² 10¹ 10⁰
100 10 1
= 100 + 20 + 3 = 123
Binary System (Base 2)
- Digits: 0, 1
- Place values: 2⁰, 2¹, 2², 2³, …
- Usage: Computer internal representation
- Example: 1011 = 1×2³ + 0×2² + 1×2¹ + 1×2⁰ = 11
⚠️ Important: Computers work internally only with 0 and 1. All data is ultimately stored as binary numbers!
Visual representation:
1 0 1 1
↓ ↓ ↓ ↓
2³ 2² 2¹ 2⁰
8 4 2 1
= 8 + 0 + 2 + 1 = 11
Hexadecimal System (Base 16)
- Digits: 0-9, A, B, C, D, E, F
- Place values: 16⁰, 16¹, 16², 16³, …
- Usage: Compact binary representation, colors, memory addresses
- Example: A3 = 10×16¹ + 3×16⁰ = 163
💡 Pro-Tip: 1 hex digit = 4 binary digits. Hexadecimal is perfect for representing binary since it’s more compact and readable!
Visual representation:
A 3
↓ ↓
16¹ 16⁰
16 1
= 160 + 3 = 163
Octal System (Base 8)
- Digits: 0, 1, 2, 3, 4, 5, 6, 7
- Place values: 8⁰, 8¹, 8², 8³, …
- Usage: Historical use in Unix systems
- Example: 75 = 7×8¹ + 5×8⁰ = 61
📜 Historical note: Octal was commonly used in early Unix systems (e.g., file permissions with
chmod 755). Today, hexadecimal is more widespread.
Visual representation:
7 5
↓ ↓
8¹ 8⁰
8 1
= 56 + 5 = 61
Exam Essentials
- Decimal system: Base 10, digits 0-9, place values 10ⁿ
- Binary system: Base 2, digits 0-1, computer representation
- Hexadecimal system: Base 16, digits 0-9, A-F, compact representation
- Conversion: Division/multiplication by base, place value method
- Bit operations: AND, OR, XOR, NOT, shift operations
- Two’s complement: Negative numbers in binary
- IHK-relevant: Foundation for computer architecture and programming
Core Components
- Number systems: Decimal, binary, hexadecimal, octal
- Conversion: Between different bases
- Bit operations: AND, OR, XOR, NOT, shift
- Two’s complement: Negative numbers
- Computer arithmetic: Addition, subtraction, multiplication
- Data types: Bits, bytes, words
- Memory representation: Hexadecimal addresses
- Error detection: Parity, checksums
Step-by-Step Conversions
💡 Pro-Tip: Practice these conversions regularly—they’re fundamental to understanding computer systems! Plus, they appear in almost every IHK AP1 or AP2 exam.
Our free online and offline calculator:
Zahlensystem-Umrechnung
Decimal to Binary (Division by 2)
Example: 13₁₀ → Binary
13 ÷ 2 = 6 remainder 1 ← least significant bit
6 ÷ 2 = 3 remainder 0
3 ÷ 2 = 1 remainder 1
1 ÷ 2 = 0 remainder 1 ← most significant bit
Read from bottom to top: 1101₂
Binary to Decimal (Place Value Method)
Example: 1101₂ → Decimal
1 1 0 1
↓ ↓ ↓ ↓
2³ 2² 2¹ 2⁰
8 4 2 1
= 1×8 + 1×4 + 0×2 + 1×1
= 8 + 4 + 0 + 1
= 13₁₀
Decimal to Hexadecimal (Division by 16)
Example: 255₁₀ → Hex
255 ÷ 16 = 15 remainder 15 (F)
15 ÷ 16 = 0 remainder 15 (F)
Read from bottom to top: FF₁₆
Hexadecimal to Binary (4-Bit Groups)
Example: A3₁₆ → Binary
A (10) 3
↓ ↓
1010 0011
Combined: 10100011₂
Binary to Hexadecimal (4-Bit Groups)
Example: 10100011₂ → Hex
1010 0011
↓ ↓
A 3
Combined: A3₁₆
Practical Examples
1. Converting Between Number Systems
public class NumberSystemConversion {
// Decimal to binary
public static String decimalToBinary(int decimal) {
if (decimal == 0) return "0";
StringBuilder binary = new StringBuilder();
while (decimal > 0) {
binary.append(decimal % 2);
decimal /= 2;
}
return binary.reverse().toString();
}
// Binary to decimal
public static int binaryToDecimal(String binary) {
int decimal = 0;
int power = 0;
for (int i = binary.length() - 1; i >= 0; i--) {
if (binary.charAt(i) == '1') {
decimal += Math.pow(2, power);
}
power++;
}
return decimal;
}
// Decimal to hexadecimal
public static String decimalToHex(int decimal) {
if (decimal == 0) return "0";
char[] hexDigits = {'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
StringBuilder hex = new StringBuilder();
while (decimal > 0) {
int remainder = decimal % 16;
hex.append(hexDigits[remainder]);
decimal /= 16;
}
return hex.reverse().toString();
}
// Hexadecimal to decimal
public static int hexToDecimal(String hex) {
int decimal = 0;
String hexDigits = "0123456789ABCDEF";
for (int i = 0; i < hex.length(); i++) {
char digit = hex.charAt(i);
int value = hexDigits.indexOf(digit);
decimal = decimal * 16 + value;
}
return decimal;
}
// Binary to hexadecimal
public static String binaryToHex(String binary) {
// Pad binary to multiple of 4
while (binary.length() % 4 != 0) {
binary = "0" + binary;
}
StringBuilder hex = new StringBuilder();
for (int i = 0; i < binary.length(); i += 4) {
String nibble = binary.substring(i, i + 4);
int value = binaryToDecimal(nibble);
hex.append(decimalToHex(value));
}
return hex.toString();
}
// Hexadecimal to binary
public static String hexToBinary(String hex) {
String[] binaryMap = {
"0000", "0001", "0010", "0011",
"0100", "0101", "0110", "0111",
"1000", "1001", "1010", "1011",
"1100", "1101", "1110", "1111"
};
StringBuilder binary = new StringBuilder();
for (int i = 0; i < hex.length(); i++) {
char digit = hex.charAt(i);
int value = "0123456789ABCDEF".indexOf(digit);
binary.append(binaryMap[value]);
}
// Remove leading zeros
while (binary.length() > 1 && binary.charAt(0) == '0') {
binary.deleteCharAt(0);
}
return binary.toString();
}
public static void main(String[] args) {
int number = 175;
System.out.println("Number: " + number);
System.out.println("Binary: " + decimalToBinary(number));
System.out.println("Hex: " + decimalToHex(number));
String binary = "10101111";
String hex = "AF";
System.out.println("\nBinary " + binary + " = Decimal " + binaryToDecimal(binary));
System.out.println("Hex " + hex + " = Decimal " + hexToDecimal(hex));
System.out.println("Binary " + binary + " = Hex " + binaryToHex(binary));
System.out.println("Hex " + hex + " = Binary " + hexToBinary(hex));
}
}
2. Bit Operations Across Languages
// Java Bit Operations
public class BitOperationen {
public static void main(String[] args) {
int a = 12; // 1100 in binary
int b = 10; // 1010 in binary
System.out.println("a = " + a + " (Binary: " + Integer.toBinaryString(a) + ")");
System.out.println("b = " + b + " (Binary: " + Integer.toBinaryString(b) + ")");
// Bitwise AND (&)
int and = a & b; // 1100 & 1010 = 1000 (8)
System.out.println("a & b = " + and + " (Binary: " + Integer.toBinaryString(and) + ")");
// Bitwise OR (|)
int or = a | b; // 1100 | 1010 = 1110 (14)
System.out.println("a | b = " + or + " (Binary: " + Integer.toBinaryString(or) + ")");
// Bitwise XOR (^)
int xor = a ^ b; // 1100 ^ 1010 = 0110 (6)
System.out.println("a ^ b = " + xor + " (Binary: " + Integer.toBinaryString(xor) + ")");
// Bitwise NOT (~)
int notA = ~a; // ~1100 = 0011 (using two's complement)
System.out.println("~a = " + notA + " (Binary: " + Integer.toBinaryString(notA) + ")");
// Left Shift (<<)
int leftShift = a << 2; // 1100 << 2 = 110000 (48)
System.out.println("a << 2 = " + leftShift + " (Binary: " + Integer.toBinaryString(leftShift) + ")");
// Right Shift (>>)
int rightShift = a >> 1; // 1100 >> 1 = 0110 (6)
System.out.println("a >> 1 = " + rightShift + " (Binary: " + Integer.toBinaryString(rightShift) + ")");
// Unsigned Right Shift (>>>)
int unsignedRightShift = a >>> 1; // 1100 >>> 1 = 0110 (6)
System.out.println("a >>> 1 = " + unsignedRightShift + " (Binary: " + Integer.toBinaryString(unsignedRightShift) + ")");
// Practical applications
praktischeAnwendungen();
}
private static void praktischeAnwendungen() {
System.out.println("\n=== Practical Applications ===");
// Check if a bit is set (is the 3rd bit set?)
int zahl = 12; // 1100
int bitPosition = 2;
boolean bitSet = (zahl & (1 << bitPosition)) != 0;
System.out.println("Bit " + bitPosition + " in " + zahl + " is set: " + bitSet);
// Set a bit
int mitBit = zahl | (1 << bitPosition);
System.out.println("Set bit " + bitPosition + ": " + mitBit);
// Clear a bit
int ohneBit = zahl & ~(1 << bitPosition);
System.out.println("Clear bit " + bitPosition + ": " + ohneBit);
// Toggle a bit
int umgeschaltet = zahl ^ (1 << bitPosition);
System.out.println("Toggle bit " + bitPosition + ": " + umgeschaltet);
// Extract color from RGB values
int farbe = 0xFF6B35; // Orange
int rot = (farbe >> 16) & 0xFF;
int gruen = (farbe >> 8) & 0xFF;
int blau = farbe & 0xFF;
System.out.println("\nColor: #" + Integer.toHexString(farbe).toUpperCase());
System.out.println("Red: " + rot);
System.out.println("Green: " + gruen);
System.out.println("Blue: " + blau);
}
}
3. Two’s Complement for Negative Numbers
⚠️ Important: Two’s complement is the standard for negative numbers in modern computers. Avoid one’s complement and sign-magnitude representation!
public class Zweierkomplement {
// Calculate two's complement
public static String zweierkomplement(int zahl, int bits) {
if (zahl >= 0) {
return String.format("%" + bits + "s", Integer.toBinaryString(zahl)).replace(' ', '0');
}
// Negative number: 2^bits + zahl
int positiv = (int) (Math.pow(2, bits) + zahl);
return String.format("%" + bits + "s", Integer.toBinaryString(positiv)).replace(' ', '0');
}
// Convert from two's complement to decimal
public static int vonZweierkomplement(String binaer) {
int bits = binaer.length();
// If the highest bit is 0, it's a positive number
if (binaer.charAt(0) == '0') {
return Integer.parseInt(binaer, 2);
}
// Negative number: - (2^bits - value)
int wert = Integer.parseInt(binaer, 2);
return wert - (int) Math.pow(2, bits);
}
public static void main(String[] args) {
int[] zahlen = {13, 5, 0, -1, -5, -13};
int bits = 8;
System.out.println("Two's complement with " + bits + " bits:");
System.out.println("Number\tBinary\t\tDecimal");
System.out.println("------\t------\t\t-------");
for (int zahl : zahlen) {
String binaer = zweierkomplement(zahl, bits);
System.out.println(zahl + "\t" + binaer + "\t" + vonZweierkomplement(binaer));
}
// Show range
System.out.println("\nRange with " + bits + " bits:");
System.out.println("Minimum: " + (-(int) Math.pow(2, bits-1)));
System.out.println("Maximum: " + ((int) Math.pow(2, bits-1) - 1));
// Demonstrate overflow
System.out.println("\nOverflow demonstration:");
int max = (int) Math.pow(2, bits-1) - 1;
int ueberlauf = max + 1;
System.out.println("Max: " + max + " -> " + zweierkomplement(max, bits));
System.out.println("Max+1: " + ueberlauf + " -> " + zweierkomplement(ueberlauf, bits));
System.out.println("Expected: " + (-(int) Math.pow(2, bits-1)) + " -> " + zweierkomplement(-(int) Math.pow(2, bits-1), bits));
}
}
4. Computer Arithmetic
⚠️ Warning: Binary arithmetic can lead to overflows. Always check the range limits of your data types!
public class Computerarithmetik {
// Binary addition
public static String binaerAddition(String a, String b) {
int laenge = Math.max(a.length(), b.length());
// Pad with leading zeros
a = String.format("%" + laenge + "s", a).replace(' ', '0');
b = String.format("%" + laenge + "s", b).replace(' ', '0');
StringBuilder ergebnis = new StringBuilder();
int carry = 0;
// Add from right to left
for (int i = laenge - 1; i >= 0; i--) {
int summe = carry + (a.charAt(i) - '0') + (b.charAt(i) - '0');
ergebnis.append(summe % 2);
carry = summe / 2;
}
// Add final carry if needed
if (carry > 0) {
ergebnis.append(carry);
}
return ergebnis.reverse().toString();
}
// Binary subtraction (using two's complement method)
public static String binaerSubtraktion(String a, String b) {
// Negate b (two's complement)
String negiert = zweierkomplementNegieren(b);
// a + (-b)
return binaerAddition(a, negiert);
}
private static String zweierkomplementNegieren(String binaer) {
// Invert bits
StringBuilder invertiert = new StringBuilder();
for (char bit : binaer.toCharArray()) {
invertiert.append(bit == '0' ? '1' : '0');
}
// Add 1
return binaerAddition(invertiert.toString(), "1");
}
// Binary multiplication
public static String binaerMultiplikation(String a, String b) {
int aDez = Integer.parseInt(a, 2);
int bDez = Integer.parseInt(b, 2);
int produkt = aDez * bDez;
return Integer.toBinaryString(produkt);
}
// Fixed-point arithmetic
public static double festePunktAddition(double a, double b, int nachkommastellen) {
int faktor = (int) Math.pow(10, nachkommastellen);
int aInt = (int) Math.round(a * faktor);
int bInt = (int) Math.round(b * faktor);
int ergebnisInt = aInt + bInt;
return (double) ergebnisInt / faktor;
}
// Floating-point representation (simplified)
public static void gleitkommaDarstellung(double zahl) {
if (zahl == 0) {
System.out.println("0 = 0.0 × 2^0");
return;
}
boolean negativ = zahl < 0;
zahl = Math.abs(zahl);
int exponent = 0;
// Normalize
while (zahl >= 2.0) {
zahl /= 2.0;
exponent++;
}
while (zahl < 1.0) {
zahl *= 2.0;
exponent--;
}
System.out.println((negativ ? "-" : "") + zahl + " × 2^" + exponent);
}
public static void main(String[] args) {
System.out.println("=== Binary Arithmetic ===");
String a = "1011"; // 11
String b = "1101"; // 13
System.out.println("a = " + a + " (" + Integer.parseInt(a, 2) + ")");
System.out.println("b = " + b + " (" + Integer.parseInt(b, 2) + ")");
String summe = binaerAddition(a, b);
System.out.println("a + b = " + summe + " (" + Integer.parseInt(summe, 2) + ")");
String differenz = binaerSubtraktion(b, a);
System.out.println("b - a = " + differenz + " (" + Integer.parseInt(differenz, 2) + ")");
String produkt = binaerMultiplikation(a, b);
System.out.println("a × b = " + produkt + " (" + Integer.parseInt(produkt, 2) + ")");
System.out.println("\n=== Fixed-Point Arithmetic ===");
double x = 12.34;
double y = 5.67;
double summeFP = festePunktAddition(x, y, 2);
System.out.println(x + " + " + y + " = " + summeFP + " (2 decimal places)");
System.out.println("\n=== Floating-Point Representation ===");
double[] zahlen = {12.5, 0.75, -3.125, 256.0};
for (double zahl : zahlen) {
System.out.print(zahl + " = ");
gleitkommaDarstellung(zahl);
}
}
}
5. Python Bit Operations and Number Systems
# Python number systems and bit operations
def decimal_to_binary(decimal):
"""Convert decimal to binary"""
if decimal == 0:
return "0"
binary = ""
while decimal > 0:
binary = str(decimal % 2) + binary
decimal //= 2
return binary
def binary_to_decimal(binary):
"""Convert binary to decimal"""
return int(binary, 2)
def decimal_to_hex(decimal):
"""Convert decimal to hexadecimal"""
hex_digits = "0123456789ABCDEF"
if decimal == 0:
return "0"
hex = ""
while decimal > 0:
hex = hex_digits[decimal % 16] + hex
decimal //= 16
return hex
def hex_to_decimal(hex):
"""Convert hexadecimal to decimal"""
return int(hex, 16)
def bit_operations_demo():
"""Demonstrate bit operations"""
a = 12 # 1100
b = 10 # 1010
print(f"a = {a} (Binary: {bin(a)})")
print(f"b = {b} (Binary: {bin(b)})")
# Bitwise AND
and_result = a & b
print(f"a & b = {and_result} (Binary: {bin(and_result)})")
# Bitwise OR
or_result = a | b
print(f"a | b = {or_result} (Binary: {bin(or_result)})")
# Bitwise XOR
xor_result = a ^ b
print(f"a ^ b = {xor_result} (Binary: {bin(xor_result)})")
# Bitwise NOT
not_a = ~a
print(f"~a = {not_a} (Binary: {bin(not_a & 0xFFFFFFFF)})")
# Left Shift
left_shift = a << 2
print(f"a << 2 = {left_shift} (Binary: {bin(left_shift)})")
# Right Shift
right_shift = a >> 1
print(f"a >> 1 = {right_shift} (Binary: {bin(right_shift)})")
def color_from_rgb(red, green, blue):
"""Pack RGB color as 24-bit value"""
return (red << 16) | (green << 8) | blue
def rgb_from_color(color):
"""Extract RGB components from 24-bit color"""
red = (color >> 16) & 0xFF
green = (color >> 8) & 0xFF
blue = color & 0xFF
return red, green, blue
def bit_manipulation_demo():
"""Demonstrate bit manipulation"""
number = 0b10101000 # 168
print(f"Original number: {number} (Binary: {bin(number)})")
# Check bit
bit_position = 3
bit_set = (number & (1 << bit_position)) != 0
print(f"Bit {bit_position} set: {bit_set}")
# Set bit
with_bit = number | (1 << bit_position)
print(f"Set bit {bit_position}: {with_bit} (Binary: {bin(with_bit)})")
# Clear bit
without_bit = number & ~(1 << bit_position)
print(f"Clear bit {bit_position}: {without_bit} (Binary: {bin(without_bit)})")
# Toggle bit
toggled = number ^ (1 << bit_position)
print(f"Toggle bit {bit_position}: {toggled} (Binary: {bin(toggled)})")
def main():
"""Main program with all demonstrations"""
print("=== Number System Conversions ===")
number = 175
print(f"Decimal {number}:")
print(f" Binary: {decimal_to_binary(number)}")
print(f" Hex: {decimal_to_hex(number)}")
print("\n=== Bit Operations ===")
bit_operations_demo()
print("\n=== Bit Manipulation ===")
bit_manipulation_demo()
print("\n=== Colors as RGB ===")
orange = color_from_rgb(255, 107, 53)
print(f"Orange: #{orange:06X}")
r, g, b = rgb_from_color(orange)
print(f"RGB: ({r}, {g}, {b})")
print("\n=== Two's Complement (8-Bit) ===")
for i in range(-5, 6):
if i >= 0:
binary = format(i, '08b')
else:
binary = format((256 + i), '08b')
print(f"{i:3d}: {binary}")
if __name__ == "__main__":
main()
Real-World Examples
1. IP Addresses (IPv4)
IPv4 addresses consist of 4 bytes (32 bits), typically written in decimal notation:
Example: 192.168.1.1
192 168 1 1
↓ ↓ ↓ ↓
11000000 10101000 00000001 00000001
C0 A8 01 01 (Hex)
Binary: 11000000101010000000000100000001
Hex: C0A80101
Subnet Mask Example: 255.255.255.0
255 255 255 0
↓ ↓ ↓ ↓
11111111 11111111 11111111 00000000
FF FF FF 00 (Hex)
2. MAC Addresses
MAC addresses are 6 bytes (48 bits), typically written in hexadecimal notation:
Example: 00:1A:2B:3C:4D:5E
00:1A:2B:3C:4D:5E
↓ ↓ ↓ ↓ ↓ ↓
00000000:00011010:00101011:00111100:01001101:01011110
Manufacturer (OUI): 00:1A:2B
Device ID: 3C:4D:5E
3. Unicode and UTF-8
Unicode characters are represented as code points, and UTF-8 encodes these into bytes:
Example: ‘A’ (U+0041)
Unicode: U+0041
Decimal: 65
Binary: 01000001
UTF-8: 01000001 (1 byte)
Example: ’€’ (U+20AC)
Unicode: U+20AC
Decimal: 8364
Binary: 00100000 10101100
UTF-8: 11100010 10000011 10101100 (3 bytes)
Hex: E2 82 AC
4. Color Codes (RGB)
Web colors are represented as 24-bit hexadecimal values:
Example: #FF6B35 (Orange)
#FF6B35
↓↓↓↓↓↓
Red Green Blue
FF 6B 35
↓ ↓ ↓
255 107 53
Binary: 11111111 01101011 00110101
Java Example:
int orange = 0xFF6B35;
int red = (orange >> 16) & 0xFF; // 255
int green = (orange >> 8) & 0xFF; // 107
int blue = orange & 0xFF; // 53
5. File Sizes (Binary vs. Decimal)
Binary Prefixes (IEC 80000-13):
1 KiB = 2¹⁰ = 1,024 bytes
1 MiB = 2²⁰ = 1,048,576 bytes
1 GiB = 2³⁰ = 1,073,741,824 bytes
Decimal Prefixes (SI):
1 KB = 10³ = 1,000 bytes
1 MB = 10⁶ = 1,000,000 bytes
1 GB = 10⁹ = 1,000,000,000 bytes
Example: 1 GB Hard Drive
Manufacturer (decimal): 1,000,000,000 bytes
Operating system (binary): 1,000,000,000 ÷ 1,073,741,824 = 0.93 GB
6. ASCII Table (Selection)
| Character | Decimal | Hex | Binary |
|---|---|---|---|
| A | 65 | 41 | 01000001 |
| B | 66 | 42 | 01000010 |
| C | 67 | 43 | 01000011 |
| a | 97 | 61 | 01100001 |
| b | 98 | 62 | 01100010 |
| c | 99 | 63 | 01100011 |
| 0 | 48 | 30 | 00110000 |
| 9 | 57 | 39 | 00111001 |
Interactive Exercises
Conversion Exercises
Exercise 1: Decimal to Binary Convert the following decimal numbers to binary:
- 42
- 127
- 255
Show solutions
42₁₀ = 101010₂
127₁₀ = 1111111₂
255₁₀ = 11111111₂Exercise 2: Binary to Decimal Convert the following binary numbers to decimal:
- 10101
- 11110000
- 10000000
Show solutions
10101₂ = 21₁₀
11110000₂ = 240₁₀
10000000₂ = 128₁₀Exercise 3: Decimal to Hexadecimal Convert the following decimal numbers to hexadecimal:
- 100
- 255
- 4095
Show solutions
100₁₀ = 64₁₆
255₁₀ = FF₁₆
4095₁₀ = FFF₁₆Exercise 4: Hexadecimal to Binary Convert the following hexadecimal numbers to binary:
- A5
- FF
- 1B
Show solutions
A5₁₆ = 10100101₂
FF₁₆ = 11111111₂
1B₁₆ = 00011011₂Bit Operations Quiz
Question 1: What is the result of 12 & 10?
Show solution
12₁₀ = 1100₂
10₁₀ = 1010₂
1100 & 1010 = 1000₂ = 8₁₀Question 2: What is the result of 12 | 10?
Show solution
12₁₀ = 1100₂
10₁₀ = 1010₂
1100 | 1010 = 1110₂ = 14₁₀Question 3: What is the result of 12 ^ 10?
Show solution
12₁₀ = 1100₂
10₁₀ = 1010₂
1100 ^ 1010 = 0110₂ = 6₁₀Question 4: What is the result of 8 << 2?
Show solution
8₁₀ = 1000₂
1000 << 2 = 100000₂ = 32₁₀Question 5: What is the result of 16 >> 2?
Show solution
16₁₀ = 10000₂
10000 >> 2 = 100₂ = 4₁₀Challenge Exercises
Exercise 6: Bit Manipulation Given the number 42 (101010₂). Set the 3rd bit (from the right, 0-indexed).
Show Solution
42 = 101010₂
3rd bit from right = bit position 2
42 | (1 << 2) = 42 | 4 = 46₁₀ = 101110₂Exercise 7: Two’s Complement Represent -5 in 8-bit two’s complement.
Show Solution
5₁₀ = 00000101₂
Invert: 11111010₂
+ 1: 11111011₂
-5₁₀ = 11111011₂ (8-bit two's complement)Exercise 8: IP Address Convert the IP address 10.0.0.1 to hexadecimal.
Show Solution
10.0.0.1
↓ ↓ ↓ ↓
0A 00 00 01
Hex: 0A000001Common Pitfalls and Mistakes
1. Off-by-one Errors in Bit Positions
Problem: Bit positions are frequently miscounted (0-indexed vs. 1-indexed)
// ❌ Wrong: Bit position 3 is the 4th bit from the right
int bitPosition = 3;
boolean bitSet = (zahl & (1 << bitPosition)) != 0; // Checks bit 3 (4th bit)
// ✅ Correct: Document the indexing clearly
// Bit position 0 = rightmost bit (LSB)
// Bit position 7 = leftmost bit in 8-bit
int bitPosition = 2; // 3rd bit from right (0-indexed)
boolean bitSet = (zahl & (1 << bitPosition)) != 0;
2. Sign Handling During Shifts
Problem: Right-shift behaves differently for signed vs. unsigned integers
// Java: Signed right shift (>>) fills with sign bit
int x = -8; // 11111111111111111111111111111000
int result = x >> 2; // 11111111111111111111111111111110 (-2)
// Unsigned right shift (>>>) fills with 0
int x = -8;
int result = x >>> 2; // 00111111111111111111111111111110 (1073741822)
3. Overflow Issues
Problem: Integer overflow often goes unnoticed
// ❌ No overflow check
int max = Integer.MAX_VALUE; // 2147483647
int overflow = max + 1; // -2147483648 (overflow!)
// ✅ With overflow check
if (max == Integer.MAX_VALUE) {
throw new ArithmeticException("Integer overflow");
}
4. Misunderstanding Hex Conventions
Problem: Different notations exist for hexadecimal numbers
// Various conventions:
0xFF // Java/C prefix
0xFF // C# prefix
0xFF // JavaScript prefix
#FF // CSS/Web
FFh // Assembler
$FF // Pascal
5. Forgetting Endianness
Problem: Byte order is often overlooked
// Little endian (x86, ARM): least significant byte first
int value = 0x12345678;
// In memory: 78 56 34 12
// Big endian (network, PowerPC): most significant byte first
// In memory: 12 34 56 78
// Conversion:
int littleEndian = 0x12345678;
int bigEndian = Integer.reverseBytes(littleEndian); // 0x78563412
6. Incorrect Radix in parseInt
Problem: The radix is not specified correctly
// ❌ Wrong: Decimal instead of binary
int value = Integer.parseInt("1010"); // 1010 (decimal)
// ✅ Correct: Specify the radix
int value = Integer.parseInt("1010", 2); // 10 (decimal)
int hexValue = Integer.parseInt("FF", 16); // 255 (decimal)
7. Exceeding Two’s Complement Range
Problem: Number doesn’t fit within the specified bit width
// 8-bit two's complement: -128 to 127
int value = 200; // ❌ Exceeds range!
// Range check:
if (value < -128 || value > 127) {
throw new IllegalArgumentException("Value outside 8-bit range");
}
8. Float vs. Integer Division
Problem: Integer division truncates decimal places
// ❌ Wrong: Integer division
int result = 5 / 2; // 2 (instead of 2.5)
// ✅ Correct: Float division
double result = 5.0 / 2.0; // 2.5
9. Negation vs. Complement
Problem: Confusing logical negation with bitwise complement
// Logical NOT (!)
boolean a = true;
boolean b = !a; // false
// Bitwise NOT (~)
int x = 5; // 0101
int y = ~x; // 1010 (with two's complement: -6)
10. Leading Zeros in Hex
Problem: Leading zeros can change meaning in certain contexts
// In Java: 0x0F = 15, 0xF = 15 (same)
// But in string comparisons:
String a = "0F";
String b = "F";
// a.equals(b) = false!
Practical Tips for Developers
1. Debugging with Binary/Hex View
Leverage IDE tools:
// IntelliJ/Eclipse: Binary view in debugger
// Variable: 175
// Binary: 10101111
// Hex: AF
Log values in different bases:
System.out.println("Decimal: " + zahl);
System.out.println("Binary: " + Integer.toBinaryString(zahl));
System.out.println("Hex: " + Integer.toHexString(zahl));
System.out.println("Octal: " + Integer.toOctalString(zahl));
2. Bit Flags in APIs
Efficient status flags:
// Define flag constants
public static final int READ = 1 << 0; // 0001
public static final int WRITE = 1 << 1; // 0010
public static final int EXECUTE = 1 << 2; // 0100
// Combine flags
int permissions = READ | WRITE; // 0011
// Check flags
boolean canRead = (permissions & READ) != 0;
boolean canWrite = (permissions & WRITE) != 0;
boolean canExecute = (permissions & EXECUTE) != 0;
3. Performance Benefits of Bit Operations
Multiplication/division via shifts:
// Faster than * 2
int x = 5;
int doubled = x << 1; // 10
// Faster than / 2
int halved = x >> 1; // 2
// Modulo 2^n with AND
int modulo8 = x & 0x7; // x % 8
⚠️ Note: Modern compilers often optimize automatically—use bit shifts only in performance-critical code.
4. Manipulating Color Values
Process RGB colors efficiently:
// Create color
int color = (255 << 16) | (107 << 8) | 53; // #FF6B35
// Extract components
int red = (color >> 16) & 0xFF;
int green = (color >> 8) & 0xFF;
int blue = color & 0xFF;
// Manipulate color
int newColor = color & 0x00FFFFFF; // Clear red component
newColor |= (200 << 16); // Set new red value
5. Network Byte Order
Ensure portability:
// Host to network short (16-bit)
short hostPort = 8080;
short networkPort = Short.reverseBytes(hostPort);
// Network to host long (32-bit)
int networkAddress = 0xC0A80101; // 192.168.1.1
int hostAddress = Integer.reverseBytes(networkAddress);
6. Bitmasks for Configuration
Store configuration compactly:
public class Config {
private int flags = 0;
public static final int DEBUG = 1 << 0;
public static final int VERBOSE = 1 << 1;
public static final int LOGGING = 1 << 2;
public void setFlag(int flag) {
flags |= flag;
}
public void clearFlag(int flag) {
flags &= ~flag;
}
public boolean hasFlag(int flag) {
return (flags & flag) != 0;
}
}
7. Memory-Efficient Data Structures
Use bits for boolean values:
// Instead of 8 booleans (8 bytes):
// boolean[] flags = new boolean[8];
// One int (4 bytes) for 8 flags:
int flags = 0;
flags |= (1 << 3); // Set 3rd flag
8. Hash Functions with Bit Operations
Simple hash function:
public static int simpleHash(String s) {
int hash = 0;
for (int i = 0; i < s.length(); i++) {
hash = (hash << 5) - hash + s.charAt(i);
}
return hash;
}
9. Parity Calculation
Parity bit for error detection:
public static boolean calculateParity(int x) {
boolean parity = false;
while (x != 0) {
parity = !parity;
x = x & (x - 1); // Clears the lowest set bit
}
return parity;
}
10. Power-of-2 Check
Efficient test for powers of two:
public static boolean isPowerOfTwo(int x) {
return x > 0 && (x & (x - 1)) == 0;
}
// Examples:
// isPowerOfTwo(1) = true (2⁰)
// isPowerOfTwo(2) = true (2¹)
// isPowerOfTwo(4) = true (2²)
// isPowerOfTwo(8) = true (2³)
// isPowerOfTwo(6) = false
Advanced Topics
1. BCD (Binary Coded Decimal)
BCD encodes each decimal digit in 4 bits:
Example: 42 in BCD
4 2
↓ ↓
0100 0010
BCD: 01000010
Advantages:
- Simple conversion to and from decimal
- Precise decimal arithmetic
Disadvantages:
- Inefficient storage (6 out of 16 values unused)
- More complex arithmetic
Java implementation:
public class BCD {
public static int decimalToBCD(int decimal) {
int bcd = 0;
int shift = 0;
while (decimal > 0) {
int digit = decimal % 10;
bcd |= (digit << shift);
decimal /= 10;
shift += 4;
}
return bcd;
}
public static int bcdToDecimal(int bcd) {
int decimal = 0;
int multiplier = 1;
while (bcd > 0) {
int digit = bcd & 0xF;
decimal += digit * multiplier;
bcd >>= 4;
multiplier *= 10;
}
return decimal;
}
}
2. Gray Code
Gray Code is a binary numeral system where consecutive values differ by only one bit:
Gray Code Table (4 bit):
Decimal | Binary | Gray Code
--------|--------|----------
0 | 0000 | 0000
1 | 0001 | 0001
2 | 0010 | 0011
3 | 0011 | 0010
4 | 0100 | 0110
5 | 0101 | 0111
6 | 0110 | 0101
7 | 0111 | 0100
Binary to Gray Code:
public static int binaryToGray(int binary) {
return binary ^ (binary >> 1);
}
Gray Code to Binary:
public static int grayToBinary(int gray) {
int binary = gray;
while (gray > 0) {
gray >>= 1;
binary ^= gray;
}
return binary;
}
Applications: Rotary encoders, error minimization in switches
3. CRC (Cyclic Redundancy Check)
CRC is an error detection method for data transmission:
Simple CRC-8 implementation:
public class CRC8 {
private static final int POLYNOMIAL = 0x07;
public static int calculate(byte[] data) {
int crc = 0x00;
for (byte b : data) {
crc ^= b;
for (int i = 0; i < 8; i++) {
if ((crc & 0x80) != 0) {
crc = (crc << 1) ^ POLYNOMIAL;
} else {
crc <<= 1;
}
}
}
return crc & 0xFF;
}
}
Used in:
- Network protocols (Ethernet, USB)
- File integrity checking
- Memory error detection
4. IEEE 754 Floating Point Format
Standard representation for floating-point numbers:
32-Bit Single Precision:
Bit 31: Sign (S)
Bits 30-23: Exponent (E, 8 bit)
Bits 22-0: Mantissa (M, 23 bit)
Value = (-1)^S × 2^(E-127) × (1 + M)
Example: 12.5 in IEEE 754
12.5 = 1100.1₂ = 1.1001₂ × 2³
S = 0 (positive)
E = 127 + 3 = 130 = 10000010₂
M = 10010000000000000000000
IEEE 754: 01000001010010000000000000000000
Hex: 41480000
Java implementation:
public class IEEE754 {
public static String floatToBits(float value) {
int bits = Float.floatToIntBits(value);
return String.format("%32s", Integer.toBinaryString(bits))
.replace(' ', '0');
}
public static float bitsToFloat(String bits) {
int intValue = Integer.parseInt(bits, 2);
return Float.intBitsToFloat(intValue);
}
}
5. Endianness (Byte Order)
Big Endian: Most significant byte first (Network Byte Order) Little Endian: Least significant byte first (x86, ARM)
Example: 0x12345678
Big Endian: 12 34 56 78
Little Endian: 78 56 34 12
Conversion in Java:
public class Endianness {
// Little Endian to Big Endian
public static int littleToBig(int value) {
return Integer.reverseBytes(value);
}
// Big Endian to Little Endian
public static int bigToLittle(int value) {
return Integer.reverseBytes(value);
}
// Check system endianness
public static boolean isLittleEndian() {
int test = 0x12345678;
byte[] bytes = new byte[] {
(byte) (test >> 24),
(byte) (test >> 16),
(byte) (test >> 8),
(byte) test
};
return bytes[0] == 0x78; // Little Endian
}
}
Critical for:
- Network protocols (TCP/IP uses Big Endian)
- File formats
- Cross-platform development
6. Parity Bit
A simple error detection technique:
Even Parity:
Data: 1011
Parity: 0 (to make the count of 1s even: 10110 → 3 ones = odd ❌)
Parity: 1 (to make the count of 1s even: 10111 → 4 ones = even ✅)
Java implementation:
public class Parity {
public static boolean calculateEvenParity(byte data) {
int count = Integer.bitCount(data & 0xFF);
return (count % 2) == 0;
}
public static byte setEvenParity(byte data) {
if (calculateEvenParity(data)) {
return (byte) (data & 0x7F); // Parity bit = 0
} else {
return (byte) (data | 0x80); // Parity bit = 1
}
}
}
7. Checksums
Simple checksums for data integrity:
Simple Checksum:
public class Checksum {
public static int calculate(byte[] data) {
int sum = 0;
for (byte b : data) {
sum += (b & 0xFF);
}
return sum & 0xFFFF; // 16-bit checksum
}
public static boolean verify(byte[] data, int checksum) {
return calculate(data) == checksum;
}
}
8. Base64 Encoding
Encode binary data as ASCII characters:
Example:
Binary: 01000001 01000010 01000011 (ABC)
Base64: QUJD
Java implementation:
import java.util.Base64;
public class Base64Example {
public static String encode(String input) {
return Base64.getEncoder().encodeToString(input.getBytes());
}
public static String decode(String encoded) {
byte[] decoded = Base64.getDecoder().decode(encoded);
return new String(decoded);
}
}
9. Bit Rotation
Rotation without losing bits:
Left Rotation:
public static int rotateLeft(int value, int shift) {
return (value << shift) | (value >>> (32 - shift));
}
Right Rotation:
public static int rotateRight(int value, int shift) {
return (value >>> shift) | (value << (32 - shift));
}
Example:
int x = 0b11000000; // 192
int rotated = rotateLeft(x, 2); // 0b00000011 (3)
10. Hamming Distance
The count of differing bits between two values:
public static int hammingDistance(int a, int b) {
int xor = a ^ b;
return Integer.bitCount(xor);
}
// Example:
// hammingDistance(0b1010, 0b1100) = 2
// 1010 ^ 1100 = 0110 (2 ones)
Use cases: Error-correcting codes, cryptography
Number System Reference Table
| Decimal | Binary | Hexadecimal | Octal |
|---|---|---|---|
| 0 | 0000 | 0 | 0 |
| 1 | 0001 | 1 | 1 |
| 2 | 0010 | 2 | 2 |
| 3 | 0011 | 3 | 3 |
| 4 | 0100 | 4 | 4 |
| 5 | 0101 | 5 | 5 |
| 6 | 0110 | 6 | 6 |
| 7 | 0111 | 7 | 7 |
| 8 | 1000 | 8 | 10 |
| 9 | 1001 | 9 | 11 |
| 10 | 1010 | A | 12 |
| 11 | 1011 | B | 13 |
| 12 | 1100 | C | 14 |
| 13 | 1101 | D | 15 |
| 14 | 1110 | E | 16 |
| 15 | 1111 | F | 17 |
Bitwise Operations Overview
Bit-Operationen
| Operator | Symbol | Description | Example |
|----------|--------|-------------|----------|
| AND | & | Bitwise AND | 5 & 3 = 1 |
| OR | \| | Bitwise OR | `5 \| 3 = 7` |
| XOR | ^ | Exclusive OR | `5 ^ 3 = 6` |
| NOT | ~ | Bitwise NOT | `~5 = -6` |
| Left Shift | << | Left shift | `5 << 2 = 20` |
| Right Shift | >> | Right shift | `5 >> 1 = 2` |
| Unsigned Right Shift | >>> | Unsigned right shift | `5 >>> 1 = 2` |
Memory Sizes
| Unit | Bytes | Bits | Unsigned Range |
|---|---|---|---|
| Byte | 1 | 8 | 0 - 255 |
| Word | 2 | 16 | 0 - 65,535 |
| DWord | 4 | 32 | 0 - 4,294,967,295 |
| QWord | 8 | 64 | 0 - 18,446,744,073,709,551,615 |
Two’s Complement Range
| Bits | Minimum | Maximum |
|---|---|---|
| 8 | -128 | 127 |
| 16 | -32,768 | 32,767 |
| 32 | -2,147,483,648 | 2,147,483,647 |
| 64 | -9,223,372,036,854,775,808 | 9,223,372,036,854,775,807 |
Pros and Cons
Advantages of Binary
- Simple: Only two states (0 and 1)
- Reliable: Easy to implement without errors
- Efficient: Optimal for electronic circuits
- Universal: Foundation of all digital systems
Advantages of Hexadecimal
- Compact: 4 binary digits = 1 hex digit
- Readable: Shorter and clearer than binary
- Standard: Widely used in programming
- Practical: Ideal for addresses and colors
Disadvantages
- Abstract: Not intuitive for humans
- Conversion: Requires mental arithmetic
- Error-prone: Easy to make mistakes in manual conversion
Common Exam Questions
1. **Convert 175 (decimal) to binary and hexadecimal!**
175₁₀ = 10101111₂ = AF₁₆
2. **What is the result of 12 & 10 (bitwise AND)?**
12₁₀ = 1100₂, 10₁₀ = 1010₂ → 1100 & 1010 = 1000₂ = 8₁₀
3. **Explain two's complement!**
A method for representing negative numbers in binary by inverting all bits and adding 1.
4. **What are hexadecimal numbers used for?**
Compact representation of binary values, colors, memory addresses, and error codes.
Key References
- https://en.wikipedia.org/wiki/Numeral_system
- https://en.wikipedia.org/wiki/Two%27s_complement
- https://docs.oracle.com/javase/tutorial/java/nutsandbolts/op3.html



