Aller au contenu

%FLOAT

Convertir en virgule flottante

Convertit un nombre ou un texte en réel (virgule flottante). Le réel couvre de très grandes plages, mais il n'est pas exact en base dix.

Syntaxe

%FLOAT(expression)
expression
Un nombre, une expression numérique ou une zone caractère contenant un nombre.
Résultat
Un nombre à virgule flottante. Affiché avec %CHAR, il sort en notation scientifique.

À quoi ça sert

Les calculs scientifiques ou statistiques (moyennes, écarts, très grands ou très petits nombres) se font plutôt en flottant, qui couvre une plage immense. %FLOAT force un calcul en flottant à un endroit précis d'une expression : %float(1) / 3 se calcule en flottant, alors que 1 / 3 reste décimal.

Exemple 1 : Réel, décimal et 0,1 + 0,2

**free
// %FLOAT : convertir en virgule flottante, et ce que cela change (ou pas) au calcul.
ctl-opt dftactgrp(*no) actgrp(*new);

dcl-s montant packed(9:2) inz(1250.50);
dcl-s a       packed(3:1) inz(0.1);
dcl-s b       packed(3:1) inz(0.2);
dcl-s somme   float(8);
dcl-s reel    float(8);
dcl-s retour  packed(5:1);
dcl-s texte   varchar(10) inz('12.5');

snd-msg 'Reel du montant  : ' + %char(%float(montant));
snd-msg 'Reel du texte    : ' + %char(%float(texte));
snd-msg '1 / 3 en reel    : ' + %char(%float(1) / 3);
snd-msg '1 / 3 decimal    : ' + %char(1 / 3);

// Le piege : 0.1 + 0.2 n'est pas exactement 0.3 en flottant.
reel = %float(a) + %float(b);
snd-msg '0.1 + 0.2 = 0.3 ? decimal : ' + %char((a + b) = 0.3);
snd-msg '0.1 + 0.2 = 0.3 ? reel    : ' + %char(reel = 0.3);
somme = reel - 0.3;
snd-msg 'Ecart en reel            : ' + %char(somme);

// Retour au decimal, arrondi
retour = %dech(reel : 3 : 1);
snd-msg 'Retour en decimal arrondi : ' + %char(retour);

*inlr = *on;

Résultat réel, compilé et exécuté sur IBM i 7.5 :

Reel du montant  : +1.250500000000000E+003
Reel du texte    : +1.250000000000000E+001
1 / 3 en reel    : +3.333333333333333E-001
1 / 3 decimal    : .33333333333333333333333333333
0.1 + 0.2 = 0.3 ? decimal : 1
0.1 + 0.2 = 0.3 ? reel    : 0
Ecart en reel            : +5.551115123125783E-017
Retour en decimal arrondi : .3

Le montant 1250,50 devient +1.250500000000000E+003 : mantisse et exposant. Le tiers en flottant compte 16 chiffres, le tiers décimal en compte 29.

La deuxième moitié montre le piège : en décimal, 0,1 + 0,2 vaut bien 0,3 (résultat 1). En flottant, la comparaison est fausse (0) : l'écart est de l'ordre de 5.55E-017. Le retour en décimal avec %DECH donne 0,3.

Le piège

Un réel ne représente pas exactement 0,1 ni 0,2. Leur somme n'égale pas 0,3 : l'exemple affiche 0 pour la comparaison et un écart de 5,55E-017. Ne jamais faire de test d'égalité sur des réels, ni calculer des montants en flottant. Pour l'argent, rester en décimal empaqueté.

Autre surprise : %CHAR d'un réel donne la notation scientifique, pas 1250.50. Convertir d'abord avec %DEC ou %DECH.