conversions.py

Note de lecture générée automatiquement

Le vrai fichier est scripts/maths/conversions.py (Obsidian n’affiche pas les scripts eux-mêmes). Ne modifie pas cette note : modifie le script, puis relance python3 generer_vues_obsidian.py dans le dossier scripts.

Code

#!/usr/bin/env python3
"""
conversions.py — Numération : décimal, binaire, hexadécimal, complément à 2,
virgule fixe et bit de parité ASCII. Affiche les étapes pour réviser.
 
Utilisation :
    python3 conversions.py dec 46            # 46 -> binaire (divisions successives) et hexa
    python3 conversions.py bin 10100110      # binaire -> décimal et hexa
    python3 conversions.py hex D4A           # hexa -> décimal et binaire
    python3 conversions.py signe -58         # complément à 2 sur 8 bits
    python3 conversions.py virgule 13.75     # virgule fixe 4 bits entiers + 4 bits fraction
    python3 conversions.py parite a          # code ASCII 7 bits + bit de parité
"""
import sys
 
 
def decimal_vers_binaire_etapes(n: int) -> str:
    if n == 0:
        return "0"
    restes = []
    while n > 0:
        quotient, reste = divmod(n, 2)
        print(f"  {n} = 2 × {quotient} + {reste}")
        restes.append(str(reste))
        n = quotient
    return "".join(reversed(restes))           # lecture des restes de bas en haut
 
 
def binaire_vers_decimal_etapes(binaire: str) -> int:
    termes = []
    total = 0
    for rang, bit in enumerate(reversed(binaire)):
        if bit == "1":
            termes.append(str(2 ** rang))
            total += 2 ** rang
    print("  " + " + ".join(reversed(termes)) + f" = {total}")
    return total
 
 
def complement_a_deux(n: int, nb_bits: int = 8) -> str:
    if not -(2 ** (nb_bits - 1)) <= n < 2 ** (nb_bits - 1):
        raise ValueError(f"{n} hors de la plage signée sur {nb_bits} bits")
    if n >= 0:
        return format(n, f"0{nb_bits}b")
    print(f"  Négatif : 2^{nb_bits} - {-n} = {2 ** nb_bits + n}")
    return format(2 ** nb_bits + n, f"0{nb_bits}b")
 
 
def virgule_fixe(valeur: float, bits_entiers: int = 4, bits_fraction: int = 4) -> str:
    partie_entiere = int(valeur)
    fraction = valeur - partie_entiere
    bits_fraction_txt = ""
    for _ in range(bits_fraction):
        fraction *= 2
        bit = int(fraction)
        bits_fraction_txt += str(bit)
        fraction -= bit
    return f"{partie_entiere:0{bits_entiers}b} {bits_fraction_txt}"
 
 
if __name__ == "__main__":
    if len(sys.argv) != 3:
        sys.exit(__doc__)
    mode, valeur = sys.argv[1], sys.argv[2]
    if mode == "dec":
        nombre = int(valeur)
        print(f"Divisions successives de {nombre} par 2 :")
        binaire = decimal_vers_binaire_etapes(nombre)
        print(f"=> binaire : {binaire}   hexa : {nombre:X}")
    elif mode == "bin":
        print(f"Somme des puissances de 2 de ({valeur})₂ :")
        nombre = binaire_vers_decimal_etapes(valeur)
        print(f"=> décimal : {nombre}   hexa : {nombre:X}")
    elif mode == "hex":
        nombre = int(valeur, 16)
        termes = [f"{int(c, 16)}×16^{r}" for r, c in enumerate(reversed(valeur.upper()))]
        print("  " + " + ".join(reversed(termes)) + f" = {nombre}")
        print(f"=> décimal : {nombre}   binaire : {nombre:b}")
    elif mode == "signe":
        print(f"=> {valeur} sur 8 bits (complément à 2) : {complement_a_deux(int(valeur))}")
    elif mode == "virgule":
        print(f"=> {valeur} en virgule fixe (4,4) : {virgule_fixe(float(valeur))}")
    elif mode == "parite":
        code = ord(valeur[0])
        sept_bits = format(code, "07b")
        bit_parite = sept_bits.count("1") % 2      # 1 si nombre de 1 impair -> total pair
        print(f"'{valeur[0]}' = ASCII {code} = {sept_bits} ({sept_bits.count('1')} bits à 1)")
        print(f"=> octet avec parité paire : {bit_parite}{sept_bits}")
    else:
        sys.exit(__doc__)