Number Systems: Binary, Hexadecimal, Decimal & Bit Operations
This article is a comprehensive introduction to number systems – including binary, hexadecimal, decimal, 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.
Compact Technical Description
Number systems are methods for representing numbers with different bases. Computers internally use the binary system (base 2), while humans prefer the decimal system (base 10).
Important 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⁰
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
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
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
Exam-Relevant Key Points
- 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 with base, place value method
- Bit operations: AND, OR, XOR, NOT, shift operations
- Two’s complement: Negative numbers in binary system
- 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
Practical Examples
1. Conversion Between Number Systems
public class ZahlensystemUmrechnung {
// Dezimal zu Binär
public static String dezimalZuBinaer(int dezimal) {
if (dezimal == 0) return "0";
StringBuilder binaer = new StringBuilder();
while (dezimal > 0) {
binaer.append(dezimal % 2);
dezimal /= 2;
}
return binaer.reverse().toString();
}
// Binär zu Dezimal
public static int binaerZuDezimal(String binaer) {
int dezimal = 0;
int potenz = 0;
for (int i = binaer.length() - 1; i >= 0; i--) {
if (binaer.charAt(i) == '1') {
dezimal += Math.pow(2, potenz);
}
potenz++;
}
return dezimal;
}
// Dezimal zu Hexadezimal
public static String dezimalZuHex(int dezimal) {
if (dezimal == 0) return "0";
char[] hexZiffern = {'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
StringBuilder hex = new StringBuilder();
while (dezimal > 0) {
int rest = dezimal % 16;
hex.append(hexZiffern[rest]);
dezimal /= 16;
}
return hex.reverse().toString();
}
// Hexadezimal zu Dezimal
public static int hexZuDezimal(String hex) {
int dezimal = 0;
String hexZiffern = "0123456789ABCDEF";
for (int i = 0; i < hex.length(); i++) {
char ziffer = hex.charAt(i);
int wert = hexZiffern.indexOf(ziffer);
dezimal = dezimal * 16 + wert;
}
return dezimal;
}
// Binär zu Hexadezimal
public static String binaerZuHex(String binaer) {
// Binär in 4er-Gruppen aufteilen
while (binaer.length() % 4 != 0) {
binaer = "0" + binaer;
}
StringBuilder hex = new StringBuilder();
for (int i = 0; i < binaer.length(); i += 4) {
String nibble = binaer.substring(i, i + 4);
int wert = binaerZuDezimal(nibble);
hex.append(dezimalZuHex(wert));
}
return hex.toString();
}
// Hexadezimal zu Binär
public static String hexZuBinaer(String hex) {
String[] binaerMap = {
"0000", "0001", "0010", "0011",
"0100", "0101", "0110", "0111",
"1000", "1001", "1010", "1011",
"1100", "1101", "1110", "1111"
};
StringBuilder binaer = new StringBuilder();
for (int i = 0; i < hex.length(); i++) {
char ziffer = hex.charAt(i);
int wert = "0123456789ABCDEF".indexOf(ziffer);
binaer.append(binaerMap[wert]);
}
// Führende Nullen entfernen
while (binaer.length() > 1 && binaer.charAt(0) == '0') {
binaer.deleteCharAt(0);
}
return binaer.toString();
}
public static void main(String[] args) {
int zahl = 175;
System.out.println("Zahl: " + zahl);
System.out.println("Binär: " + dezimalZuBinaer(zahl));
System.out.println("Hex: " + dezimalZuHex(zahl));
String binaer = "10101111";
String hex = "AF";
System.out.println("\nBinär " + binaer + " = Dezimal " + binaerZuDezimal(binaer));
System.out.println("Hex " + hex + " = Dezimal " + hexZuDezimal(hex));
System.out.println("Binär " + binaer + " = Hex " + binaerZuHex(binaer));
System.out.println("Hex " + hex + " = Binär " + hexZuBinaer(hex));
}
}
2. Bit Operations in Various 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 (with 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 bit (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 + " set: " + bitSet);
// Set bit
int mitBit = zahl | (1 << bitPosition);
System.out.println("Set bit " + bitPosition + ": " + mitBit);
// Clear bit
int ohneBit = zahl & ~(1 << bitPosition);
System.out.println("Clear bit " + bitPosition + ": " + ohneBit);
// Toggle 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
public class Zweierkomplement {
// Zweierkomplement berechnen
public static String zweierkomplement(int zahl, int bits) {
if (zahl >= 0) {
return String.format("%" + bits + "s", Integer.toBinaryString(zahl)).replace(' ', '0');
}
// Negative Zahl: 2^bits - |zahl|
int positiv = (int) (Math.pow(2, bits) + zahl);
return String.format("%" + bits + "s", Integer.toBinaryString(positiv)).replace(' ', '0');
}
// Aus Zweierkomplement Dezimalwert berechnen
public static int vonZweierkomplement(String binaer) {
int bits = binaer.length();
// Wenn höchstes Bit 0 ist, positive Zahl
if (binaer.charAt(0) == '0') {
return Integer.parseInt(binaer, 2);
}
// Negative Zahl: - (2^bits - wert)
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));
}
// Bereichsanzeige
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));
// Überlauf demonstrieren
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
public class Computerarithmetik {
// Binäre Addition
public static String binaerAddition(String a, String b) {
int laenge = Math.max(a.length(), b.length());
// Mit führenden Nullen auffüllen
a = String.format("%" + laenge + "s", a).replace(' ', '0');
b = String.format("%" + laenge + "s", b).replace(' ', '0');
StringBuilder ergebnis = new StringBuilder();
int carry = 0;
// Von rechts nach links addieren
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;
}
// Carry am Ende hinzufügen
if (carry > 0) {
ergebnis.append(carry);
}
return ergebnis.reverse().toString();
}
// Binäre Subtraktion (Zweierkomplement-Methode)
public static String binaerSubtraktion(String a, String b) {
// b negieren (Zweierkomplement)
String negiert = zweierkomplementNegieren(b);
// a + (-b)
return binaerAddition(a, negiert);
}
private static String zweierkomplementNegieren(String binaer) {
// Bits invertieren
StringBuilder invertiert = new StringBuilder();
for (char bit : binaer.toCharArray()) {
invertiert.append(bit == '0' ? '1' : '0');
}
// 1 addieren
return binaerAddition(invertiert.toString(), "1");
}
// Binäre Multiplikation
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);
}
// Feste-Punkt-Arithmetik
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;
}
// Gleitkomma-Darstellung (vereinfacht)
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;
// Normalisieren
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 dezimal_zu_binaer(dezimal):
"""Convert decimal to binary"""
if dezimal == 0:
return "0"
binaer = ""
while dezimal > 0:
binaer = str(dezimal % 2) + binaer
dezimal //= 2
return binaer
def binaer_zu_dezimal(binaer):
"""Convert binary to decimal"""
return int(binaer, 2)
def dezimal_zu_hex(dezimal):
"""Convert decimal to hexadecimal"""
hex_ziffern = "0123456789ABCDEF"
if dezimal == 0:
return "0"
hex = ""
while dezimal > 0:
hex = hex_ziffern[dezimal % 16] + hex
dezimal //= 16
return hex
def hex_zu_dezimal(hex):
"""Convert hexadecimal to decimal"""
return int(hex, 16)
def bit_operationen_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 farbe_aus_rgb(rot, gruen, blau):
"""Combine RGB color as 24-bit value"""
return (rot << 16) | (gruen << 8) | blau
def rgb_aus_farbe(farbe):
"""Extract RGB components from 24-bit color"""
rot = (farbe >> 16) & 0xFF
gruen = (farbe >> 8) & 0xFF
blau = farbe & 0xFF
return rot, gruen, blau
def bit_manipulation_demo():
"""Demonstrate bit manipulation"""
zahl = 0b10101000 # 168
print(f"Original number: {zahl} (Binary: {bin(zahl)})")
# Check bit
bit_position = 3
bit_gesetzt = (zahl & (1 << bit_position)) != 0
print(f"Bit {bit_position} set: {bit_gesetzt}")
# Set bit
mit_bit = zahl | (1 << bit_position)
print(f"Set bit {bit_position}: {mit_bit} (Binary: {bin(mit_bit)})")
# Clear bit
ohne_bit = zahl & ~(1 << bit_position)
print(f"Clear bit {bit_position}: {ohne_bit} (Binary: {bin(ohne_bit)})")
# Toggle bit
umgeschaltet = zahl ^ (1 << bit_position)
print(f"Toggle bit {bit_position}: {umgeschaltet} (Binary: {bin(umgeschaltet)})")
def hauptprogramm():
"""Main program with all demonstrations"""
print("=== Number System Conversion ===")
zahl = 175
print(f"Decimal {zahl}:")
print(f" Binary: {dezimal_zu_binaer(zahl)}")
print(f" Hex: {dezimal_zu_hex(zahl)}")
print("\n=== Bit Operations ===")
bit_operationen_demo()
print("\n=== Bit Manipulation ===")
bit_manipulation_demo()
print("\n=== Colors as RGB ===")
orange = farbe_aus_rgb(255, 107, 53)
print(f"Orange: #{orange:06X}")
r, g, b = rgb_aus_farbe(orange)
print(f"RGB: ({r}, {g}, {b})")
print("\n=== Two's Complement (8-Bit) ===")
for i in range(-5, 6):
if i >= 0:
binaer = format(i, '08b')
else:
binaer = format((256 + i), '08b')
print(f"{i:3d}: {binaer}")
if __name__ == "__main__":
hauptprogramm()
Conversion 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 |
Bit Operations Overview
| 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 | << | Shift left | 5 << 2 = 20 |
| Right Shift | >> | Shift right | 5 >> 1 = 2 |
| Unsigned Right Shift | >>> | Unsigned right shift | 5 >>> 1 = 2 |
Storage Sizes
| Unit | Bytes | Bits | Range (unsigned) |
|---|---|---|---|
| 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 |
Advantages and Disadvantages
Advantages of Binary System
- 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 System
- Compact: 4 binary digits = 1 hexadecimal digit
- Readable: Shorter and clearer than binary
- Standard: Widely used in programming
- Practical: Ideal for addresses and colors
Disadvantages
- Abstraction: 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!**
Method for representing negative numbers in the binary system through bit inversion and adding 1.
4. **What are hexadecimal numbers used for?**
Compact representation of binary values, colors, memory addresses, error codes.
Most Important Sources
- https://de.wikipedia.org/wiki/Zahlensystem
- https://de.wikipedia.org/wiki/Zweierkomplement
- https://docs.oracle.com/javase/tutorial/java/nutsandbolts/op3.html