RETROGICIEL
DECIMALES INFINIES
RETROGICIEL
DECIMALES INFINIES
⇩. Présentation
S'il y a bien une chose que les ordinateurs savent faire, c'est calculer. Mais, le plus souvent, le résultat retourné dépend des limites de la représentation des nombres flottants, avec un l’arrondi automatique, ou de la notation scientifique.
Réalisons donc un petit programme qui effectuera une division en reproduisant fidèlement le mécanisme de la division posée. Il permettra de produire une partie décimale beaucoup plus précise, avec un nombre de décimales, pouvant être théoriquement infinie, entièrement contrôlé par l’utilisateur.
Les saisies de l'utilisateur sont controlées avant le calcul afin d’éviter qu'une erreur soit retournée. La division sera effectuée chiffre par chiffre, ce qui garantit une construction exacte du quotient décimal. Le programme s’arrête lorsque la division sera exacte ou lorsque le nombre de décimales souhaité est atteint. Nous obtiendrons ainsi un outil de précision pour obtenir des résultats décimaux détaillés, là où les calculs standards des CPU montrent leurs limites.
⇩. Consignes
Le programme doit :
demander les deux termes de la division, dividende et diviseur ;
demander le nombre de décimales du résultat ;
controler les saisies pour éviter une erreur lors des calculs ;
simuler le calcul d'une division posée ;
controler si le nombre de décimales est atteint et ;
controler si la division est complétée ;
afficher le résultat ;
-demander si l'utilisateur veut effectuer un autre calcul.
D'abord, faite-le fonctionner. Ensuite, faite-le beau. Enfin, faite-le performant.
Amusez-vous bien !
Télécharger RETROGICIEL - Decimales infinies.
Cette présentation nécessite que Python 3 soit installé sur votre machine.
Après avoir téléchargé le fichier Decimales infinies.7z, décompressez-le dans le répertoire de votre choix.
Ouvrez le répertoire qui vient d'être créé.
Lancez le fichier Retrogiciel.py.
Cliquez sur l'onglet RUN et testez le programme.
Créez votre propre script dans un des langages proposés ou un autre de votre choix.
Le répertoire contient aussi :
- Python.py, l'exemple en PYTHON sans tkinter ;
- Tkinter.py, l'exemple en PYTHON avec tkinter ;
- Qb84.bas, l'exemple en QBASIC avec qb64 ;
- Bbc.bas, l'exemple en BBC BASIC avec bbc sdl.
# --- Origine Nerd ---
# --- RETROGICIEL - PYTHON ---
# --- Décimales infinies ---
# -*- coding: utf-8 -*-
# --- DÉFINITION DES FONCTIONS PERSONNALISEES ---
# --- Calculs de la division et affichage ---
def FNC_Calculs ( Qdividende , Qdiviseur , Qdecimales ) :
# --- Deplacement de la virgule (le diviseur doit être un int ) ---
kpuissance = len ( Qdiviseur.split ( "." ) [ 1 ] ) if "." in Qdiviseur else 0
kdividende = str ( abs ( float ( Qdividende ) * ( 10 ** kpuissance ) ) )
kdiviseur = int ( abs ( float ( Qdiviseur ) * ( 10 ** kpuissance ) ) )
# --- Initialisation les valeurs du premier calcule de la chaine ---
kreste = 0
kresultat = ""
# --- Boucle des calculs ---
while True :
# --- Initialisation des termes du calcul ---
ktransit = str ( kreste ) + kdividende [ 0 ]
kdividende = "0" if len( kdividende ) == 1 else kdividende [ 1 : ]
# --- Opération et MaJ du résultat ---
kquotien , kreste = divmod ( int ( ktransit ) , kdiviseur )
kresultat = kresultat + str ( kquotien )
# --- Début de la partie décimale du résultat ---
if kdividende [ 0 ] == "." :
kresultat += "."
kdividende = kdividende [ 1 : ]
# --- Controles si des opérations sont encore utiles ---
if int ( ktransit ) == 0 and float ( kdividende ) == 0.0 :
kdecimales = len ( kresultat.split ( "." ) [ 1 ] )
print ( f"Division complétée en { kdecimales } décimales." )
break
# --- Teste si le nombre de décimales souhaitées est atteint ---
if "." in kresultat and len ( kresultat.split ( "." ) [ 1 ] ) >= Qdecimales : break
# --- Affichage du résultat ---
kresultat = kresultat.lstrip ( "0" )
if float ( Qdividende ) / float ( Qdiviseur ) < 0 : kresultat = "-" + kresultat
print ( kresultat )
# --- Saisies et controle de validité des données ---
def FNC_Saisies ( ) :
# --- Saisies des données ---
kdividende = input ( "Saisiez le dividende ... " )
kdiviseur = input ( "Saisiez le diviseur ... " )
kdecimales = input ( "Saisiez le nombre de décimales au résultat ... " )
# --- Les données sont valides (calculs possibles) ---
try :
kdividende = str ( float ( kdividende ) )
kdiviseur = str ( float ( kdiviseur ) )
kdecimales = int ( kdecimales )
kvalide = True
# --- Les données invalides ---
except :
print( "\nERREUR DE SAISIES.\n")
kvalide = False
# --- Résolution de la division ---
if kvalide : FNC_Calculs ( kdividende , kdiviseur , kdecimales )
# --- PRESENTATION ---
print ( "DECIMALES INFINIES\n" )
# --- BOUCLE PRINCIPALE ---
while True :
FNC_Saisies ( )
kchoix = input ( "\nVoulez-vous faire un autre calcul (O ou N) ?" )
if kchoix.upper ( ) == "N" : break
# --- FIN DU PROGRAMME ---
print ( "Au revoir" )
# --- Programme : JFB ---
# --- Février 2026 ---
# --- Fin ---
Pour mieux comprendre l'exemple en PYTHON sans tkinter.
# --- Origine Nerd ---
# --- RETROGICIEL - TKINTER ---
# --- Décimales infinies ---
# -*- coding: utf-8 -*-
# --- IMPORTATION DES MODULES ---
# --- Modules de la bibliothèque standard ---
import tkinter
# --- DÉFINITION DES FONCTIONS PERSONNALISEES ---
# --- Calculs de la division et affichage ---
def FNC_Calculs ( Qdividende , Qdiviseur , Qdecimales ) :
# --- Initialisation les valeurs du premier calcule de la chaine ---
BOX_Operations.delete ( 0 , "end" )
kreste = 0
kresultat = ""
# --- Deplacement de la virgule (le diviseur doit être un int ) ---
if Qdiviseur.split ( "." ) [ 1 ] != "0" :
kpuissance = len ( Qdiviseur.split ( "." ) [ 1 ] ) if "." in Qdiviseur else 0
kdividende = str ( abs ( float ( Qdividende ) * ( 10 ** kpuissance ) ) )
kdiviseur = int ( abs ( float ( Qdiviseur ) * ( 10 ** kpuissance ) ) )
else :
kdividende = str ( abs ( float ( Qdividende ) ) )
kdiviseur = int ( abs ( float ( Qdiviseur ) ) )
# --- Affichage des valeurs réellement calculées ---
LAB_Dividende [ "text" ] = kdividende
LAB_Diviseur [ "text" ] = kdiviseur
# --- Boucle des calculs ---
while True :
# --- Initialisation des termes du calcul ---
ktransit = str ( kreste ) + kdividende [ 0 ]
kdividende = "0" if len( kdividende ) == 1 else kdividende [ 1 : ]
# --- Opération et MaJ du résultat ---
kquotien , kreste = divmod ( int ( ktransit ) , kdiviseur )
kresultat = kresultat + str ( kquotien )
koperation = f"{ ktransit } ÷ { kdiviseur } = { kquotien } (reste : { kreste } ⬇{ kdividende [ 0 ] } "
BOX_Operations.insert ( "end" , koperation )
# --- Début de la partie décimale du résultat ---
if kdividende [ 0 ] == "." :
kresultat += "."
kdividende = kdividende [ 1 : ]
# --- Controles si des opérations sont encore utiles ---
if int ( ktransit ) == 0 and float ( kdividende ) == 0.0 :
kdecimales = len ( kresultat.split ( "." ) [ 1 ] )
print ( f"Division complétée en { kdecimales } décimales." )
break
# --- Teste si le nombre de décimales souhaitées est atteint ---
if "." in kresultat and len ( kresultat.split ( "." ) [ 1 ] ) >= Qdecimales : break
# --- Affichage du résultat ---
kresultat = kresultat.lstrip ( "0" )
f float ( Qdividende ) / float ( Qdiviseur ) < 0 : kresultat = "-" + kresultat
LAB_Resultat [ "text" ] = kresultat
# --- Saisies et controle de validité des données ---
def FNC_Saisies ( ) :
# --- Saisies des données ---
kdividende = TKV_Dividende.get ( )
kdiviseur = TKV_Diviseur.get ( )
kdecimales = TKV_Decimales.get ( )
# --- Les données sont valides (calculs possibles) ---
try :
kdividende = str ( float ( kdividende ) )
kdiviseur = str ( float ( kdiviseur ) )
kdecimales = int ( kdecimales )
kvalide = True
# --- Les données invalides ---
except :
LAB_Resultat [ "text" ] = "ERREUR DE SAISIES."
kvalide = False
# --- Résolution de la division ---
if kvalide : FNC_Calculs ( kdividende , kdiviseur , kdecimales )
# --- CREATION DE L'INTERFACE GRAPHIQUE ---
# --- Création de la fenêtre principale ---
TKI_Principal = tkinter.Tk ( )
TKI_Principal.title ( "RETROGICIEL - Décimales infinies" )
# --- Création des variables de controles ---
TKV_Dividende = tkinter.StringVar ( )
TKV_Diviseur = tkinter.StringVar ( )
TKV_Decimales = tkinter.StringVar ( )
# --- Création du conteneur des opérations ---
FRM_Operations = tkinter.LabelFrame ( TKI_Principal , text = " Opérations ... " )
BAR_Vertical = tkinter.Scrollbar ( FRM_Operations )
BOX_Operations = tkinter.Listbox ( FRM_Operations , width = 30 )
BOX_Operations.grid ( row = 0 , column = 0 , sticky = "nesw" )
BAR_Vertical.grid ( row = 0 , column = 1 , sticky = "nesw" )
tkinter.Button ( FRM_Operations , text = "Quitter" , command = TKI_Principal.destroy ).grid ( row = 1 , column = 0 , columnspan = 2 , sticky = "nesw" )
# --- Création du conteneur des données ---
FRM_Donnees = tkinter.LabelFrame ( TKI_Principal , text = " Données ... " )
ENT_Dividende = tkinter.Entry ( FRM_Donnees , textvariable = TKV_Dividende )
ENT_Diviseur = tkinter.Entry ( FRM_Donnees , textvariable = TKV_Diviseur )
ENT_Decimales = tkinter.Entry ( FRM_Donnees , textvariable = TKV_Decimales )
LAB_Dividende = tkinter.Label ( FRM_Donnees , text = "..." , justify = "left" , anchor = "n" )
LAB_Diviseur = tkinter.Label ( FRM_Donnees , text = "..." , justify = "left" , anchor = "n" )
tkinter.Label ( FRM_Donnees , text = "Dividende : " , justify = "right" ).grid ( row = 0 , column = 0 ,sticky = "ne" )
ENT_Dividende.grid ( row = 0 , column = 1 , sticky = "nesw" )
LAB_Dividende.grid ( row = 0 , column = 2 , sticky = "nesw" )
tkinter.Label ( FRM_Donnees , text = "Diviseur : " , justify = "right" ).grid ( row = 1 , column = 0 ,sticky = "ne" )
ENT_Diviseur.grid ( row = 1 , column = 1 , sticky = "nesw" )
LAB_Diviseur.grid ( row = 1 , column = 2 , sticky = "nesw" )
tkinter.Label ( FRM_Donnees , text = "Décimales : " , justify = "right" ).grid ( row = 2 , column = 0 ,sticky = "ne" )
ENT_Decimales.grid ( row = 2 , column = 1 , sticky = "nesw" )
tkinter.Button ( FRM_Donnees , text = "Calculer" , command = FNC_Saisies ).grid ( row = 2 , column = 2 , sticky = "nesw" )
# --- Création du conteneur du résultat ---
FRM_Resultat = tkinter.LabelFrame ( TKI_Principal , text = " Résultat ... " )
LAB_Resultat = tkinter.Message ( FRM_Resultat )
LAB_Resultat.pack ( fill = "both" )
# --- Mise en place des controles (anonymes et nommés) dans la fenêtre principale ---
FRM_Operations.grid ( row = 0 , column = 0 , rowspan = 2 , sticky = "nesw" )
FRM_Donnees.grid ( row = 0 , column = 1 , sticky = "nesw" )
FRM_Resultat.grid ( row = 1 , column = 1 , sticky = "nesw" )
# --- Mise à jour des controles ---
BOX_Operations [ "yscrollcommand" ] = BAR_Vertical.set
BAR_Vertical [ "command" ] = BOX_Operations.yview
# --- DEBUT DU PROGRAMME ---
TKI_Principal.mainloop ( )
# --- Programme : JFB ---
# --- Février 2026 ---
# --- Fin ---
Pour mieux comprendre l'exemple en PYTHON avec tkinter.
' --- Origine Nerd propose pour ---
' --- RETROGICIEL - QB64 ---
' --- Decimales infinies ---
' --- DEBUT DU PROGRAMME ---
PRINT "DECIMALES INFINIES."
' --- BOUCLE PRINCIPALE ---
DO
' --- Saisies des donnees ---
INPUT "Saisiez le dividende ... "; kdividende##
INPUT "Saisiez le diviseur ... "; kdiviseur##
INPUT "Saisiez le nombre de decimales au resultat ... ... "; kdecimales&&
' --- Affichage du resultat ---
PRINT FNC_Calcul$(kdividende##, kdiviseur##, kdecimales&&)
' --- Bouclage du programme ---
PRINT ""
INPUT "Voulez-vous recommencer [ O ou N ] "; kchoix$
LOOP UNTIL UCASE$(kchoix$) = "N"
' --- FIN DU PROGRAMME ---
PRINT "Au revoir."
END
' --- DEFINITION DES FONCTIONS PERSONNALISEES ---
' --- Description de la fonction ---
FUNCTION FNC_Calcul$ (Qdividende##, Qdiviseur##, Qdecimales&&)
' --- Deplacement de la virgule (le diviseur doit etre un int ) ---
kdiviseur$ = LTRIM$(STR$(Qdiviseur##))
kpuissance = LEN(kdiviseur$) - INSTR(kdiviseur$, ".")
IF kpuissance = LEN(kdiviseur$) THEN kpuissance = 0
kdiviseur&& = ABS(Qdiviseur##) * (10 ^ kpuissance)
kdividende$ = STR$(ABS(Qdividende##) * (10 ^ kpuissance))
IF INSTR(kdividende$, ".") = 0 THEN kdividende$ = kdividende$ + ".0"
' --- Initialisation les valeurs du premier calcule de la chaine ---
kreste = 0
kresultat$ = ""
' --- Boucle des calculs ---
DO
' --- Initialisation des termes du calcul ---
ktransit$ = STR$(kreste) + LEFT$(kdividende$, 1)
IF LEN(kdividende$) > 1 THEN kdividende$ = RIGHT$(kdividende$, LEN(kdividende$) - 1) ELSE kdividende$ = "0"
' --- Operation et MaJ du résultat ---
kquotien = VAL(ktransit$) \ kdiviseur&&
kreste = VAL(ktransit$) MOD kdiviseur&&
IF kresultat$ <> "" OR kquotien <> 0 THEN kresultat$ = kresultat$ + LTRIM$(STR$(kquotien))
' --- Debut de la partie decimale du resultat ---
IF LEFT$(kdividende$, 1) = "." THEN
kresultat$ = kresultat$ + "."
kdividende$ = RIGHT$(kdividende$, LEN(kdividende$) - 1)
END IF
' --- Controles si des operations sont encore utiles ---
IF VAL(ktransit$) = 0 AND VAL(kdividende$) = 0 THEN
PRINT "Division completee !"
EXIT DO
END IF
' --- Teste si le nombre de decimales souhaitees est atteint ---
IF INSTR(kresultat$, ".") <> 0 THEN kfait = LEN(kresultat$) - INSTR(kresultat$, ".") ELSE kfait = 0
LOOP UNTIL kfait >= Qdecimales&&
' --- Affichage du résultat ---
IF LEFT$(kresultat$, 1) = "." THEN kresultat$ = "0" + kresultat$
IF Qdividende## / Qdiviseur## < 0 THEN kresultat$ = "-" + kresultat$
FNC_Calcul$ = kresultat$
END FUNCTION
' --- Programme : JFB ---
' --- Fevrier 2026 ---
' --- Fin ---
Pour mieux comprendre l'exemple en QB64.
REM --- Origine Nerd propose pour ---
REM --- RETROGICIEL - BBC BASIC ---
REM --- Decimales infinies ---
REM --- DEBUT DU PROGRAMME ---
PRINT "DECIMALES INIFINIES."
REM --- BOUCLE PRINCIPALE ---
REPEAT
PROC_Saisies
INPUT "Voulez-vous recommencer [ O ou N ] "; kchoix$
UNTIL kchoix$ = "N" OR kchoix$ = "n"
REM --- FIN DU PROGRAMME ---
PRINT "Au revoir."
END
REM --- DEFINITION DES FONCTIONS PERSONNALISEES ---
REM --- Suite des operations de la division ---
DEF FN_Calcul$( Qdividende# , Qdiviseur# , Qdecimales%% )
REM --- Deplacement de la virgule (le diviseur doit etre un int ) ---
kdiviseur$ = STR$(Qdiviseur#)
kpuissance = LEN(kdiviseur$) - INSTR(kdiviseur$, ".")
IF kpuissance = LEN(kdiviseur$) THEN kpuissance = 0
kdiviseur%% = ABS(Qdiviseur#) * (10 ^ kpuissance)
kdividende$ = STR$(ABS(Qdividende#) * (10 ^ kpuissance))
IF INSTR(kdividende$, ".") = 0 THEN kdividende$ = kdividende$ + ".0"
REM --- Initialisation les valeurs du premier calcule de la chaine ---
kreste%% = 0
kresultat$ = ""
REM --- Boucle des calculs ---
REPEAT
REM --- Initialisation des termes du calcul ---
ktransit$ = STR$(kreste%%) + LEFT$(kdividende$, 1)
IF LEN(kdividende$) > 1 THEN kdividende$ = RIGHT$(kdividende$, LEN(kdividende$) - 1) ELSE kdividende$ = "0"
REM --- Operation et MaJ du rSTR$LENsultat ---
kquotien%% = VAL(ktransit$) DIV kdiviseur%%
kreste%% = VAL(ktransit$) MOD kdiviseur%%
IF kresultat$ <> "" OR kquotien%% <> 0 THEN kresultat$ = kresultat$ + STR$(kquotien%%)
REM --- Debut de la partie decimale du resultat ---
IF LEFT$(kdividende$, 1) = "." THEN
kresultat$ = kresultat$ + "."
dividende$ = RIGHT$(kdividende$, LEN(kdividende$) - 1)
ENDIF
REM --- Controles si des operations sont encore utiles ---
IF VAL(ktransit$) = 0 AND VAL(kdividende$) = 0 THEN
PRINT "Division completee !"
EXIT REPEAT
ENDIF
REM --- Teste si le nombre de decimales souhaitees est atteint ---
IF INSTR(kresultat$, ".") <> 0 THEN kfait = LEN(kresultat$) - INSTR(kresultat$, ".") ELSE kfait = 0
UNTIL kfait >= Qdecimales%%
REM --- Affichage du resultat ---
IF LEFT$(kresultat$, 1) = "." THEN kresultat$ = "0" + kresultat$
IF Qdividende# / Qdiviseur# < 0 THEN kresultat$ = "-" + kresultat$
= kresultat$
REM --- Saisies et controle de validitSTR$LEN des donnSTR$LENes ---
DEF PROC_Saisies
REM --- Saisiedes donnees ... ---
INPUT "Saisiez le dividende ... "; kdividende#
INPUT "Saisiez le diviseur ... "; kdiviseur#
INPUT "Saisiez le nombre de decimales au resultat ... "; kdecimales%%
REM --- Controle de validite des saisies (calculs possibles) ---
kvalide = -1 : IF ( kdividende# * kdiviseur# * kdecimales%% ) = 0 THEN kvalide = 0
REM --- Effectue la division si les saisies sont valides ---
IF kvalide THEN
PRINT FN_Calcul$( kdividende# , kdiviseur# , kdecimales%% )
ELSE
PRINT "ERREUR DE SAISIES."
ENDIF
ENDPROC
REM --- Programme : JFB ---
REM --- Fevrier 2026 ---
REM --- Fin ---
Pour mieux comprendre l'exemple en BBC BASIC.