Aller au contenu

%INT

Convertir en entier

Convertit un nombre ou un texte en entier signé. La partie décimale est supprimée, pas arrondie.

Syntaxe

%INT(expression)
expression
Un nombre (packed, zoned, entier, flottant), une expression numérique, ou une zone caractère contenant un nombre.
Résultat
Un entier signé. La partie décimale est coupée vers zéro : 12,99 donne 12 et -12,99 donne -12.

À quoi ça sert

On a besoin d'un entier pour un indice de tableau, un compteur, un nombre de pages, une quantité de colis. Comme le résultat d'une division ou d'un poids est décimal, %INT retire la partie décimale de façon explicite, et le lecteur du code sait que c'est voulu.

La fonction lit aussi du texte : %INT(' 345') donne 345. Une partie décimale dans le texte est ignorée, '345.9' donne 345.

Exemple 1 : Troncature

**free
// %INT : convertir en entier - la partie decimale est TRONQUEE, pas arrondie.
ctl-opt dftactgrp(*no) actgrp(*new);

dcl-s prix     packed(7:2) inz(12.99);
dcl-s solde    packed(7:2) inz(-12.99);
dcl-s poids    float(8) inz(1234.5678);
dcl-s saisie   varchar(10) inz('  345');
dcl-s saisie2  varchar(10) inz('345.9');
dcl-s qte      int(10);

qte = %int(prix);
snd-msg '12.99 devient       : [' + %char(qte) + ']';
snd-msg '-12.99 devient      : [' + %char(%int(solde)) + ']';
snd-msg 'Reel 1234.5678      : [' + %char(%int(poids)) + ']';
snd-msg 'Texte "  345"       : [' + %char(%int(saisie)) + ']';
snd-msg 'Texte "345.9"       : [' + %char(%int(saisie2)) + ']';
snd-msg '17 / 5 dans un int  : [' + %char(%int(17 / 5)) + ']';

*inlr = *on;

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

12.99 devient       : [12]
-12.99 devient      : [-12]
Reel 1234.5678      : [1234]
Texte "  345"       : [345]
Texte "345.9"       : [345]
17 / 5 dans un int  : [3]

12,99 devient 12, -12,99 devient -12 : la coupure se fait vers zéro. Un réel 1234,5678 donne 1234. Le texte '345.9' donne 345.

Attention à 17 / 5 : c'est le résultat décimal 3,4 qui est converti, on obtient 3.

Exemple 2 : Débordement et texte invalide

**free
// %INT : debordement et texte invalide.
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(5);
dcl-s gros   packed(15:0) inz(5000000000);
dcl-s enorme float(8) inz(1e30);
dcl-s saisie varchar(10) inz('12x');
dcl-s res    int(10);

monitor;
  petit = %int(70000);
on-error *all;
  snd-msg '70000 dans int(5)  : ' + pgmsts.typ + pgmsts.num;
endmon;

monitor;
  res = %int(gros);
on-error *all;
  snd-msg '5 milliards        : ' + pgmsts.typ + pgmsts.num;
endmon;

monitor;
  res = %int(enorme);
on-error *all;
  snd-msg 'Reel 1e30          : ' + pgmsts.typ + pgmsts.num;
endmon;

monitor;
  res = %int(saisie);
on-error *all;
  snd-msg 'Texte 12x          : ' + pgmsts.typ + pgmsts.num;
endmon;

monitor;
  saisie = '';
  res = %int(saisie);
on-error *all;
  snd-msg 'Texte vide         : ' + pgmsts.typ + pgmsts.num;
endmon;

*inlr = *on;

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

70000 dans int(5)  : MCH1210
5 milliards        : MCH1210
Reel 1e30          : MCH1212
Texte 12x          : RNX0105
Texte vide         : RNX0105

Le résultat doit tenir dans la zone qui le reçoit. 70000 dans un int(5) et 5 milliards dans un int(10) donnent MCH1210. Un réel de 1e30 donne MCH1212. Un texte qui n'est pas un nombre, y compris la chaîne vide, donne RNX0105.

Le piège

Pas d'arrondi. %INT(12.99) vaut 12, pas 13 ; %INT(-12.99) vaut -12, pas -13. Pour arrondir, prendre %INTH.

Deuxième piège : un débordement ne se contente pas de couper, il plante (MCH1210). Un entier int(5) ne dépasse pas 32767. Et le texte vide plante lui aussi (RNX0105) : ne pas supposer qu'il vaut zéro.