Se familiariser avec le langage
Les deux programmes développés autour des dates du calendrier grégorien
et du Jour Julien ont suivi, ligne à ligne, la description des
algorithmes trouvés sur Wikipedia. On n'a, de même, utilisé que peu de possibilités du langage, adoptant le positionnement du débutant pourvu seulement d'ouvrages d'initiation.
Cela permet de parvenir au résultat attendu, mais tant de choses intéressantes sont laissées dans l'ombre que le lecteur ne peut découvrir en quoi ce langage mérite son attention.
Quelques exemples pris "en ligne" peuvent servir d'illustration.
Puisqu'il a été question de calculs, poursuivons dans cette voie.
Un site dédié aux calculs et aux types numériques
Malheureusement en anglais, ce site est tout de même à considérer, par l'intérêt des programmes courts présentés. Voir : Mathematical calculationsLes commentaires qui accompagnent le code suivant seront ma valeur ajoutée au travail de l'auteur.
Exemple 1 : une addition simple sur des nombres "à virgule".
Voici le code source (Les remarques qui suivent sont signalées en caractères gras)with Ada.Text_IO; procedure Numeric_1 is type Value_Type is digits 12 Remarque 1 range -999_999_999_999.0e999 .. 999_999_999_999.0e999; package T_IO renames Ada.Text_IO; Remarque 2 package F_IO is new Ada.Text_IO.Float_IO (Value_Type); Value_1 : Value_Type; Remarque 1 Value_2 : Value_Type; begin T_IO.Put ("First Value : "); F_IO.Get (Value_1); T_IO.Put ("Second Value : "); F_IO.Get (Value_2); F_IO.Put (Value_1); T_IO.Put (" + "); F_IO.Put (Value_2); T_IO.Put (" = "); F_IO.Put (Value_1 + Value_2); end Numeric_1;
Remarque 1. Dans les ordinateurs usuels les nombres sont représentés selon deux logiques différentes selon qu'ils sont :
- des nombres entiers, c'est à dire les nombres "sans virgules"
- des nombres "à virgule flottante". Sur ce sujet, lire par exemple http://fr.wikipedia.org/wiki/Virgule_flottante .
Dans les langages informatiques tels que C, Java, Ada... les nombres à virgule flottante sont définis selon des types standards : float, long_float (voire plus). Le type
float
permet une certaine précision. Le type long_float
permet une précision meilleure. Derrière ces termes (
float, long_float
...)
une réalité physique : la taille des cases prévues pour ranger les
nombres. Ces tailles pouvant varier selon les matériels, les
concepteurs-réalisateurs d'applications informatiques doivent être
certains que la précision attendue sera au rendez-vous.Ada offre une possibilité originale de déterminer, sans ambiguité, la précision des nombres à virgule flottante, par la création de types.
C'est le compilateur (et dans la norme Ada le compilateur doit être validé - c'est à dire que l'on a vérifié qu'il respectait la norme) qui, à partir du code, va régler les "problèmes d'intendance".
La déclaration suivante en est l'illustration : les nombres devront avoir 12 chiffres et les valeurs admises seront comprises entre les deux extrêmes définis ici :
de
valeur la plus basse
.. à valeur la plus haute
.type Value_Type is digits 12 range -999_999_999_999.0e999 .. 999_999_999_999.0e999;Ayant défini un type nouveau, il devient possible de l'affecter à des variables.
C'est ce que réalise le code suivant :
Value_1 : Value_Type; Value_2 : Value_Type;Ce que l'on peut traduire par : "les variables
Value_1
et Value_2
sont de type numérique, avec
une précision définie dans le type Value_type
".Remarque 2. Les
package
sont des extensions du langage.Chacun fournit des possibilités particulières, que l'on ne charge dans la mémoire que si l'application informatique en a besoin. Pour signifier au compilateur que l'on va avoir besoin de charger telles fonctionnalités, on inscrit leur noms en tête du programme via le mot "with" suivi du nom du paquet à charger.
Par exemple la commande
Put_line
qui
permet d'afficher du texte sur l'écran est contenue dans le package Ada.Texte_IO
et, pour l'appeler dans le cours du programme, il faudrait écrire :Ada.text_IO.Put_line(....)
ce qui est
assez long et impersonnel.Ada permet de donner des noms plus courts, via le mot
renames
.package T_IO renames Ada.Text_IO;
x
x
JJulien = 2456288.990116
Entiere = Tronq(2456288.990116) = 2456288
Fractionnaire = 2456288.990116 - 2456288 = 0.990116 Alfa = Tronq ((2456288 -1867216.25)/36524.25) = 16 S = 2456288 + 1 + 16 - TRoq(16/4) = 2456301 B = 2456301 + 1524 = 2457825
C = Tronq((2457825 - 122.1)/365.25) = 6728
D = Tronq(365.25*6728) = 2457402
E = Tronq((2457825 - 2457402)/30.6001) = 13 Jour = 2457825 - 2457402 - TRonq(30.6001*13)+0.5+Fractionnaire = 27.490116
Mois = 12
Annee = 2012
Particularités de Ada à connaître avant de commencer
Un document de référence sur le langage Ada
1. Avant de pouvoir utiliser une constante, une variable, il faut définir son type.2. L'affectation se fait en utilisant le signe := comme dans Pascal
Exemple : ma_variable := 50 ;
3. La fin d'une instruction est marquée par le point-virgule ; comme dans Pascal et d'autres langages.
4. Une opération entre des nombres ne peut se faire qu'entre des valeurs de même type
A := 12.45 / 2.7 ; est autorisé parce que les deux nombres sont de type float (nombres à virgules)
B := 12.45 / 3 ; est interdit parce que l'un des nombre est de type float et l'autre de type integer (nombre entier).
Conséquence de la quatrième affirmation
Le résultat final sera un nombre décimal, de typelong_float
,
pour tenir compte de la précision requise.Il s'ensuit que tous les nombres qui vont participer à ce résultat seront aussi de type
long_float
.Conséquence des affirmations 1 et 2
On définit les variables :Annee : long_float ; Mois : long_float ; Jour : long_float ; Entieres : long_float ; Fractionnaire : long_float ; Alfa : long_float ;Avant de les initialiser :
S , B , C , D , E : long_float ;
JJulien : long_float ;
Annee := 0.0 ; Mois := 0.0 ; Jour := 0.0 ; ... JJulien := 0.0 ;Le jour julien est alors saisi en utilisant une fonction, conformément au cahier des charges.
Nouveauté par rapport au programme précédent
Le code source du programme étant accessible à la fin de cet article,
nous allons commenter ici seulement ce qui est nouveau :- la saisie d'une variable
- la non exécution en cas de valeur trop petite.
Saisie d'une valeur
Celle-ci est déportée dans une function afin d'alléger le code de la
procédure principale.
function SaisieJJ return long_float is -- la saisie du Jour Julien est déportée dans une fonction prov : long_float; -- valeur locale pour la saisie begin prov:=0.0; Put("Calcul d'une date du calendrier grégorien en partant du Jour Julien");
New_Line ; Put("--------------------------------------------------------------------");
New_Line ; Put("Entrer le Jour Julien, la partie décimale"); New_Line ; Put("et la partie entière étant séparées par un point : "); Get(prov); return prov; -- retour de la valeur saisie
end SaisieJJ ;
La non exécution en cas de valeur trop petite
Elle s'effectue dans le corps de la procédure principale selon la
logique suivante :if JJulien > 2299161.0 then effectuer les calculs et afficher les résultatsCe qui est une façon très minimaliste de traiter le problème.
...
else
signaler l'erreur
end if ;
Par la suite, on verra comment faire mieux.
Et maintenant ?
Le code du programme peut être chargé ici :Code à charger
Il se compile en tapant dans une fenêtre console (Linux ou Windows):
gnatmake jjul_gregor.adb
qui génère un code exécutable que l'on peut lancer en tapant :
./jjul_gregor
ou
jjul_gregor
La suite plus tard...
Merci à octave.org: le mode de fonctionnement de ce site m'ayant plu, je
m'en suis largement inspiré (=je l'ai carrément pompé) pour ces quelques pages.