Bases Tutorial

In this page, the functions presented are rewritten and optimized versions of those we created together during a previous tutorial.

These functions use knowledge that has not necessarily been covered in class, it would be relevant to take time to reread them and conduct the necessary research to understand why and how they were rewritten this way.

Base 2 to base 10

Below is an optimal version of the bindecimal() function created in the tutorial. Some differences, beyond the docstring:

  • use of reversed() to read the string from right to left
  • use of enumerate() which allows getting both index and value during iteration
  • use of the ** operator instead of the pow() function for better readability
def bindecimal(nb_binary):
    """
    Converts a binary number (as string or integer) to decimal.

    Parameters:
    -----------
    nb_binary : str | int
        The binary number to convert (ex: "1010" or 1010).

    Returns:
    --------
    int
        The corresponding decimal value.
    """
    # Input validation
    assert isinstance(nb_binary, (str, int)), "Input must be a string or integer."
    
    # Convert to string if input is integer
    nb_binary = str(nb_binary)
    
    # Check that input is a valid binary number
    assert all(bit in "01" for bit in nb_binary), "Input must contain only 0s and 1s."

    # Convert binary to decimal
    nb_decimal = 0
    for i, bit in enumerate(reversed(nb_binary)):  # Iterate from right to left
        nb_decimal += int(bit) * (2 ** i)
        
    return nb_decimal

# Quick tests
assert bindecimal("1010") == 10
assert bindecimal(1011) == 11
assert bindecimal("0") == 0
assert bindecimal("1") == 1
assert bindecimal("1111") == 15

Base 10 to base 2

def decibin(nb_decimal):
    """
    Converts a decimal number (integer) to binary as a string.

    Parameters:
    -----------
    nb_decimal : int
        The decimal number to convert (ex: 10).

    Returns:
    --------
    str
        The binary representation of the number.
    """
    # Input validation
    if not isinstance(nb_decimal, int) or nb_decimal < 0:
        raise ValueError("Input must be a positive integer.")

    # Special case: 0 in binary is "0"
    if nb_decimal == 0:
        return "0"

    # Convert to binary with successive divisions
    nb_binary = ""
    while nb_decimal > 0:
        nb_binary = str(nb_decimal % 2) + nb_binary
        nb_decimal //= 2

    return nb_binary

# Quick tests
assert decibin(10) == "1010"
assert decibin(13) == "1101"
assert decibin(0) == "0"
assert decibin(1) == "1"
assert decibin(255) == "11111111"
assert decibin(42) == "101010"

Base 2 to base 16

def binhex(nb_binary):
    """
    Converts a binary number (as string or integer) to hexadecimal.

    Parameters:
    -----------
    nb_binary : str | int
        The binary number to convert (ex: "1010" or 1010).

    Returns:
    --------
    str
        The corresponding hexadecimal value as a string.
    """
    # Input validation
    if not isinstance(nb_binary, (str, int)):
        raise ValueError("Input must be a string or integer.")
    
    # Convert to string if input is integer
    nb_binary = str(nb_binary)
    
    # Check that input is a valid binary number
    if not all(bit in "01" for bit in nb_binary):
        raise ValueError("Input must contain only 0s and 1s.")
    
    # Add leading zeros so length is multiple of 4
    while len(nb_binary) % 4 != 0:
        nb_binary = "0" + nb_binary

    # Binary → Hex conversion dictionary
    dict_bh = {f"{i:04b}": f"{i:X}" for i in range(16)}

    # Split into 4-bit blocks and convert
    hex_result = "".join(dict_bh[nb_binary[i:i+4]] for i in range(0, len(nb_binary), 4))
    
    return hex_result

# Quick tests
assert binhex("1010") == "A"
assert binhex(1101) == "D"
assert binhex("1111") == "F"
assert binhex("11111111") == "FF"
assert binhex("0001") == "1"

Base 16 to base 2

def hex_to_bin(nb_hex):
    """
    Converts a hexadecimal number (as string) to binary.

    Parameters:
    -----------
    nb_hex : str
        The hexadecimal number to convert (ex: "A" or "1F").

    Returns:
    --------
    str
        The binary representation of the number.
    """
    # Input validation
    if not isinstance(nb_hex, str):
        raise ValueError("Input must be a string representing a hexadecimal number.")

    # Check that string contains only valid hexadecimal characters
    nb_hex = nb_hex.upper()  # Standardize to uppercase
    if not all(c in "0123456789ABCDEF" for c in nb_hex):
        raise ValueError("Input must contain only hexadecimal digits (0-9, A-F).")

    # Hex → Binary conversion dictionary
    dict_hb = {f"{i:X}": f"{i:04b}" for i in range(16)}

    # Conversion: replace each hexadecimal character with its binary equivalent
    nb_binary = "".join(dict_hb[c] for c in nb_hex)

    # Remove unnecessary leading zeros (except if result is "0")
    return nb_binary.lstrip("0") or "0"

# Quick tests
assert hex_to_bin("A") == "1010"
assert hex_to_bin("1F") == "11111"
assert hex_to_bin("FF") == "11111111"
assert hex_to_bin("0") == "0"
assert hex_to_bin("C3") == "11000011"
assert hex_to_bin("ABC") == "101010111100"