%ABS
Valeur absolue
Renvoie la valeur absolue d'un nombre ou d'une expression : le nombre sans son signe.
Syntaxe
%ABS(expression numérique)
expression numérique- Une zone, une constante ou une expression numérique.
- Résultat
- Une valeur numérique de même type que l'expression, toujours positive ou nulle. Les décimales sont conservées : -62,50 donne 62,50.
À quoi ça sert
Pour comparer un écart à une tolérance, il faut ignorer son sens : un stock réel inférieur de 62,50 au stock théorique et un stock supérieur de 62,50 sont un même écart. %ABS évite d'écrire deux tests ou un if avec multiplication par -1.
Exemple 1 : Écart de stock
**free
// %ABS : valeur absolue d'un nombre ou d'une expression.
ctl-opt dftactgrp(*no) actgrp(*new);
dcl-s theorique packed(9:2) inz(1250.00);
dcl-s reel packed(9:2) inz(1187.50);
dcl-s ecart packed(9:2);
dcl-s variation int(10) inz(-42);
dcl-s tolerance packed(9:2) inz(100.00);
dcl-s ratio float(8) inz(-0.75);
ecart = reel - theorique;
snd-msg 'Ecart signe : ' + %char(ecart);
snd-msg 'Ecart absolu : ' + %char(%abs(ecart));
snd-msg 'Variation entiere : ' + %char(%abs(variation));
snd-msg 'Expression 10 - 25 : ' + %char(%abs(10 - 25));
snd-msg 'Reel -0.75 : ' + %char(%abs(ratio));
if %abs(reel - theorique) > tolerance;
snd-msg 'Ecart hors tolerance';
else;
snd-msg 'Ecart dans la tolerance de ' + %char(tolerance);
endif;
*inlr = *on;
Résultat réel, compilé et exécuté sur IBM i 7.5 :
Ecart signe : -62.50
Ecart absolu : 62.50
Variation entiere : 42
Expression 10 - 25 : 15
Reel -0.75 : +7.500000000000000E-001
Ecart dans la tolerance de 100.00
L'écart signé vaut -62,50, l'écart absolu 62,50. La fonction accepte les entiers (-42 donne 42), les expressions (10 - 25 donne 15) et les réels (le résultat sort en notation scientifique avec %CHAR). Le test avec la tolérance de 100 tient en une ligne.
Exemple 2 : Le plus petit entier
**free
// %ABS : le plus petit entier n'a pas d'oppose positif dans le meme type.
ctl-opt dftactgrp(*no) actgrp(*new);
dcl-ds pgmsts psds qualified;
typ char(3) pos(40);
num char(4) pos(43);
end-ds;
dcl-s petit int(10) inz(-2147483648);
dcl-s res int(10);
dcl-s large int(20);
large = %abs(petit);
snd-msg 'Dans un int(20) : ' + %char(large);
monitor;
res = %abs(petit);
snd-msg 'Dans un int(10) : ' + %char(res);
on-error *all;
snd-msg 'Dans un int(10) : ' + pgmsts.typ + pgmsts.num;
endmon;
*inlr = *on;
Résultat réel, compilé et exécuté sur IBM i 7.5 :
Dans un int(20) : 2147483648
Dans un int(10) : MCH1210
Un int(10) va de -2147483648 à 2147483647 : le plus petit n'a pas d'opposé positif dans le même type. Le résultat tient dans un int(20), mais dans un int(10) le programme s'arrête avec MCH1210.
Le piège
La valeur absolue du plus petit entier ne tient pas dans le même type. %ABS(-2147483648) dans un int(10) plante avec MCH1210, alors que le même calcul réussit dans un int(20). Le risque est mince, mais il existe avec des données extrêmes.