Pour l'instant on n'a utilisé que des nombres entiers. On a vu comment les lire avec read_int()
, les afficher avec print_int()
, et faire des opérations de bases dessus : addition +
, soustraction -
, et multiplication *
. Notez que la division de deux entiers n'étant pas toujours un entier, le symbole /
prendra un sens différent de la division usuelle, comme on l'expliquera dans la prochaine section.
Pour désigner la façon dont un ordinateur manipule les nombres réels, on utilise l'expression de "nombres flottants"
, "float"
en anglais. En français les réels ont des virgules, mais en anglais il y a un point, et ainsi 4.56
vaut quatre virgule cinquante-six. Même si le nombre n'a pas de chiffres après la virgule, pour qu'il soit considéré comme un float, il faut le faire suivre d'un point. Ainsi 4.
est un réel, alors que 4
est toujours un entier. Pour les nombres négatifs, il suffit de mettre un moins devant : -234.81
par exemple. Enfin il est possible d'utiliser la notation scientifique : 1.27e12
signifie 1.27 multiplié par 10 à la puissance 12.
A chaque opération sur les entiers, il va correspondre l'analogue pour les floats. On les lira avec read_float()
, de la même manière qu'avec read_int()
. La fonction read_float()
est d'ailleurs capable de lire un réel même s'il est donné par l'utilisateur sous la forme d'un entier, comme par exemple 4
sans point à la fin. Pour afficher des float, on utilisera print_float
suivi de la valeur du réel.
Pour les opérations, il faut faire très attention car les symboles sont tous suivis d'un point. Cela traduit différentes méthodes de calculs entres les entiers et les réels. Par exemple, une addition de deux réels n'est pas réalisée par un ordinateur de la même manière que l'addition de deux entiers. On a donc l'addition +.
la soustraction -.
la multiplication *.
et enfin la division /.
qui forment les quatre opérations.
Il est impossible de mélanger des int et des float sans soins particuliers.
Voici un programme qui demande à l'utilisateur un réel, qui affiche d'une part le produit de ce nombre par 3.4
, et d'autre part la valeur de l'opposé de ce nombre.
let x = read_float() in print_float (3.4 *. x); print_newline(); print_float (-. x);
Remarque : print_float (-x)
ne marche pas, car le -
permet d'opposer des entiers, et pas des réels.
L'erreur fréquente d'oubli de parenthèses, qu'on a déjà évoqué pour les entiers :
print_float -5.448;
File "test.ml", line 1, characters 0-11: This expression has type float -> unit but is here used with type int
L'erreur se situe sur le print_float
, qui est normalement de type "float -> unit"
(c'est une fonction, on le verra). Le compilateur dit qu'on devrait normalement avoir un entier à cet endroit. L'explication est qu'il essaie d'effectuer une soustraction de deux entiers, avec le signe moins, comme cela :
(print_float) - (5.448);
Si vous tentez de mélanger des valeurs ou des opérations réelles avec des valeurs ou des opérations entières, une erreur de type se produira. Un petit exemple :
let a = read_float() in print_float (3 +. a);
Donne une erreur sur le 3
:
File "test.ml", line 2, characters 13-14: This expression has type int but is here used with type float
Ce message est facile à comprendre : le 3 qu'il désigne est un int (entier), alors qu'il devrait être un float (réel), puisqu'on a utilisé l'opérateur +.
qui additionne deux floats.
C'est bien connu, il ne faut jamais diviser par zéro. Tout simplement parce qu'on ne peut pas prévoir le résultat.
Lorsqu'on effectue une division par zéro en calculant sur des réels, un code spécial est utilisé pour désigner le résultat. Sous Windows :
1.\#INF
et-1.\#INF
respectivement pour plus et moins l'infini.1.\#IND
et-1.\#IND
pour des valeurs indéterminées.
Sous linux :
inf.
et-inf.
respectivement pour plus et moins l'infini.nan.
et-nan.
pour des valeurs indéterminées.
Voici un exemple de code faisant apparaître ces valeurs. Sous Windows :
print_float (5. /. 0.); print_newline(); print_float (-1. /. 0.); print_newline(); print_float (0. *. ( 5. /. 0.));
1.#INF -1.#INF -1.#INDEt sous Linux :
inf. -inf. nan.
Ce n'est pas très important de comprendre le fonctionnement détaillé de ces subtilités. L'essentiel est de se souvenir que l'affichage de valeurs de ce type est dû à des problèmes de calculs qui ne sont pas définis.