Découverte du langage ADA

Le calcul du jour Julien- première version

La connaissance du Jour Julien est nécessaire pour pouvoir effectuer divers calculs astronomiques, tels que décrits dans les livres de Jean Meeus.

L'article de Wikipedia sur le jour julien

Cahier des charges :
Calculer puis afficher le jour julien pour une date prise dans le calendrier grégorien.
- La date et l'heure seront introduits dans le corps du programme de façon à ne pas avoir à s'occuper de la saisie interactive.
- Il ne sera pas fait de test de cohérence des dates et heures, ni de vérification sur la cohérence avec le calendrier : ce premier programme a valeur de test et les valeurs entrées ont été choisies avec attention.
- Le résultat sera affiché sous la forme d'un nombre à virgules avec 6 décimales.

Description des calculs à effectuer.

Les valeurs à connaître sont : année, mois, jour, heure, minute, seconde pour le moment considéré.
Les calculs seront faits selon l'orde des lettres majuscules placées en début de ligne (A puis B puis C...).
A. Calcul de la valeur fractionnaire du jour correspondant à heure, minute, seconde :
Fractionnaire = heure/24 + minute/1440+ seconde/86400
(parce qu'il y a 24 heures dans un jour, 1440 minutes dans un jour, 86400 secondes dans un jour).
B. Remplacer le nombre de jours par la somme jour + fractionnaire
C. Si le mois est égal à 1 ou à 2, remplacer anne par annee -1 et mois par mois +12
D. Nos avons besoin d'une fonction (un outil...) qui permette d'éliminer les chiffres décimaux d'un nombre à virgule, sans effectuer d'arondi ni changer le signe. Cette fonction s'appellera Tronq et on l'utilisera ainsi :
valeur sans chiffres décimaux = Tronq(valeur avec tous les chiffres).
Exemples pour tester la validité :
Tronq(12,87) doit donner 12, Tronq(-19,02) doit donner -19
E. Siecle= Tronq(Annee/100)
F. Quart de siecle = Siecle/4
G. Correctif = 2- Siecle + Tronq (Quart de Siecle)
H. Etape1 = Tronq( 365,25 multiplié par la somme de Annee plus 4716)
I. Etape2 = Tronq(30,6001 multiplié par Mois +1))
J. Pour finir, le jour julien est donné par la formule :
Jour Julien = etape1 + etape2 + Jour + Correctif - 1524.5

Calcul à la main à partir d'un exemple

Annee = 2012   Mois = 12    Jour    = 27
Heure = 11     minute = 45  Seconde = 46
A. Fractionnaire = 11/24 + 45/1440 + 46/86400
Fractionnaire = 0,458333333 + 0,014322917 + 0,00024402 = 0,490115741
B. Jour = 27 + 0,490115741 = 27,490115741
C. On ne change rien à Annee et Mois
D. On suppose réalisée la fonction
E. Siecle = la partie non décimale de 2012/100 d'où...
Siecle = 20
F. Quart de siecle = 20 / 4 (donne 5)
G. Correctif = 2 - 20 + 5 = -13
H. Annee + 4716 = 2012 + 4716 = 6728
   365,25 * 6728 = 2457402
   Etape1 = Tronq(2457402) = 2457402 (rien à enlever).
I. 30,6001 * (12 + 1) = 397,8013
   Etape2 = Tronq(397,8013) = 397
J. 2457402 + 397 + 27,490115741 + (-13) -1524.5 = 2456288,990116

Réponse : Jour julien = 2456288,990116

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 (float).
Il s'ensuit que tous les nombres qui vont participer à ce résultat seront aussi de type float.

Conséquence des affirmations 1 et 2

On définit les variables :
   Annee    :  float ;        Mois     :  float ;
   Jour     :  float ;        Heure    :  float ;
   Minute   :  float ;        Seconde  :  float ;
   JJulien  :  float ;
Avant de les initialiser :
   Annee    := 2012.0 ;    Mois     := 12.0 ;
   Jour     := 27.0 ;      Heure    := 11.0 ;
   Minute   := 45.0 ;      Seconde  := 46.0 ;
   JJulien  := 0.0 ;
Ce qui conduit à une remarque :
Il serait possible de tout faire au moyen d'une seule opération :
Annee : float := 2012.0 ;
Mais il est plus méthodique de procéder en deux temps.

Structure d'un programme Ada

L'illustration suivante représente schématiquement le programme

programme simplifié

Avant d'aller plus loin : le type float, choisi initialement, était trop court pour permettre le calcul avec la précision requise. Il a fallu le remplacer par le type long_float, qui correspond au type double du C.
Maintenant, détaillons le code selon les parties.

Importer les objets externes(cadre vert)
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Long_Float_Text_IO; use Ada.Long_Float_Text_IO;
Cela nous donne accès à des éléments non contenus dans le "Ada de base". Voir article de Wikipedia si vous voulez des explications plus détaillées.

Le corps du programme est le cadre jaune, lequel comprend plusieurs parties.

La sous-partie de spécification des données
-- Partie des déclarations.
-- Constantes
-- Variables
   Annee    :  long_float ;        Mois     :  long_float ;
   Jour     :  long_float ;        Heure    :  long_float ;
   Minute   :  long_float ;        Seconde  :  long_float ;
   JJulien  :  long_float ;
-- Valeurs intermédiaires
   Fractionnaire : long_float  ;   Siecle   : long_float ;
   Quart_de_Siecle : long_float ;  Correctif : long_float ;
   etape1 : long_float ;           etape2 : long_float ;
La sous-partie contenant la fonction Tronq
Elle est donnée ici, mais sera expliquée plus loin. Pour le moment on a juste à savoir qu'elle remplit son rôle.
    function Tronq(A:long_float) return long_float is
    -- la fonction Tronq telle que décrite dans l'article
    -- http://fr.wikipedia.org/wiki/Jour_julien
    -- Tronq(X) : on élimine la partie décimale et on la remplace par 0
    -- exemple Tronq(2,3) = 2,0 ; Tronq(3,6) = 3,0 ; Tronq(-5,2) = -5,0 ;
    -- attention aux problèmes d'arrondis
    prov : integer;
    flottant : long_float;

    begin
        prov := integer(A);
        flottant := long_float(prov);
        -- résoudre les erreurs d'arrondis
        if  (A < 0.0 )
            then if flottant < A
                    then flottant:=flottant + 1.0;
                    end if ;
            else if flottant > A
                    then flottant:=flottant - 1.0;
                    end if;
        end if;
        return flottant ;
    end Tronq ;
La sous-partie principale
Elle contient les initialisations ainsi que les instructions réalisant le calcul.
begin

-- Initialisations
-- Faite dans le corps de la procédure ou par saisie avec vérifications
   Annee    := 2012.0 ;    Mois     := 12.0 ;
   Jour     := 27.0 ;      Heure    := 11.0 ;
   Minute   := 45.0 ;      Seconde  := 46.0 ;
   JJulien  := 0.0 ;       Fractionnaire  := 0.0 ;
   Siecle   := 0.0 ;       Quart_de_Siecle := 0.0 ;
   Correctif:= 0.0;        etape1   := 0.0;
   etape2   := 0.0 ;

-- Instructions
   Fractionnaire := (Heure/24.0)+(Minute/1440.0)+(Seconde/86400.0);
   Jour := Jour +  Fractionnaire ;
   Put(Item => Jour, Fore=>8, Aft=> 6, Exp=>0);
   New_Line;
   if (Mois=1.0) or (Mois=2.0)
      then Annee := Annee - 1.0 ;
            Mois := Mois + 12.0 ;
      end if ;
   Siecle            := Tronq(Annee/100.0) ;
   Quart_de_Siecle   := Siecle / 4.0 ;
   Correctif         := 2.0 - Siecle + Tronq (Quart_de_Siecle) ;
   etape1            := Tronq(365.25*(Annee+4716.0)) ;
   etape2            := Tronq(30.6001*(Mois+1.0)) ;
   JJulien := etape1 + etape2 + Jour +  Correctif - 1524.5 ;
   New_Line ;
   Put(Item => JJulien, Fore=>8, Aft=> 8, Exp=>0) ;
   -- le résultat attendu est 2 456 288 . 990 116
   -- on obtient 2456289.000000
   -- taille du type pour JJulien ?

end jjul_llong ;

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_llong.adb
qui génère un code exécutable que l'on peut lancer en tapant :
./jjul_llong
ou
jjul_llong

La suite plus tard...

Code HTML tapé avec Geany, ce qui permet
de n'y mettre QUE ce que l'on veut
et d'indenter son code comme bon vous semble.

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.