Invité Invité
| Sujet: nombres entiers et limitation Dim 10 Oct 2010 - 0:04 | |
| voici une limitation des nombres entiers. Pour arréter la boucle, appuyer sur escarpe Faisant mes essais avec l'éditeur Crimson et utilisant chain, cela ne me pose pas de problèmes, mais je pense qu'avec l'éditeur, il y aura un blocage (peut-être qu'avec Scancode que j'ai rajouté, cela ne sera pas le cas) - Code:
-
height 0,900 dim a%,b% ,c% b%= 1 for a%= 1 to 2147483648 b% = b% * 2 :print b%," ",c% c%=c%+1 if b% >=2147483648 then exit_for if scancode=27 then stop next a% print c% ," ",b% En remplaçant b% par b, pour utiliser les nombres à virgules flottantes, a% fonctionne normalement et s'arrète à 31 |
|
Invité Invité
| Sujet: Re: nombres entiers et limitation Dim 10 Oct 2010 - 0:38 | |
| Je suppose que ce problème vient de ce que je suis en train de lire sur le C et asm. Le problème est peut-être le même avec Delphi: - Citation :
- unsigned char uchar = 0xFF;
signed char schar = 0xFF; int a = (int) uchar; /* a = 255 (0x000000FF) */ int b = (int) schar ; /* b = -1 (0xFFFFFFFF) */
Fig. 2.1 ? Extension de signe en C
char ch; while( (ch = fgetc(fp)) != EOF ) { /* faire qqch avec ch */ }
Fig. 2.2 - Utilisation de la fonction fgetc
Application à la programmation en C L'extension d'entiers signés et non signés a également lieu en C. Les variables en C peuvent être déclarées soit comme signées soit comme non signées (les int sont signés). Considérons le code de la Figure 2.1. A la ligne 3, la variable a est étendue en utilisant les règles pour les valeurs non signées (avec MOVZX), mais à la ligne 4, les règles signées sont utilisées pour b (avec MOVSX). Il existe un bug de programmation courant en C qui est directement lié à notre sujet. Considérons le code de la Figure 2.2. La prototype de fgetc()est : int fgetc( FILE * ); On peut se demander pourquoi est-ce que la fonction renvoie un int puis-qu'elle lit des caractères? La raison est qu'elle renvoie normalement un char (étendu à une valeur int en utilisant l'extension de zéro). Cependant, il y a une valeur qu'elle peut retourner qui n'est pas un caractère, EOF. C'est une macro habituellement dé?nie comme valant ?1. Donc, fgetc() retourne soit un char étendu à une valeur int (qui ressemble à 000000xx en hexa) soit EOF (qui ressemble à FFFFFFFF en hexa). Le problème avec le programme de la Figure 2.2 est que fgetc() renvoie un int, mais cette valeur est stockée dans un char. Le C tronquera alors les bits de poids fort pour faire tenir la valeur de l'int dans le char. Le seul problème est que les nombres (en hexa) 000000FF et FFFFFFFF seront tous deux tronqué pour donner l'octet FF. Donc, la boucle while ne peut pas distinguer la lecture de l'octet FF dans le ?chier et la ?n de ce ?chier. Ce que fait exactement le code dans ce cas change selon que le char est signé ou non. Pourquoi? Parce que ligne 2, ch est comparé avec EOF. Comme
et aussi: - Citation :
- TRAVAILLER AVEC LES ENTIERS
EOF est un int
, ch sera étendu à un int a?n que les deux valeurs comparées soient de la même taille
. Comme la Figure 2.1 le montrait, le fait qu'une variable soit signée ou non est très important. Si le char n'est pas signé, FF est étendu et donne 000000FF. Cette valeur est comparée à EOF (FFFFFFFF) et est différente. Donc la boucle ne finit jamais! So le char est signé, FF est étendu et donne FFFFFFFF. Les deux valeurs sont alors égale et la boucle se termine. Cependant, comme l'octet FF peut avoir été lu depuis le fichier, la boucle peut se terminer prématurément. La solution à ce problème est de définir la variable ch comme un int, pas un char. Dans ce cas, aucune troncation ou extension n'est effectuée à la ligne 2. Dans la boucle, il est sans danger de tronquer la valeur puisque ch doit alors être réellement un octet. |
|