On 12 sep, 07:14, Richard Delorme wrote:Le 11/09/2009 22:53, Stephane Legras-Decussy a écrit :a écrit dans le message de news:unsigned int a = 3232235530U;pour moi c'est interdit de faire ça, ce nombre
ne rentre pas dans la plage garantie
de 0 à 65 535 ...
En quoi c'est interdit ?
C'est interdit si on cherche à écrire du code portable.
Si l'on doit se conformer strictement aux valeurs minimales de la norme
on ne programme plus grand chose.
Réponse idiote. On choisit le bon type, c'est tout. (ici, unsigned
long).
On 12 sep, 07:14, Richard Delorme<abu...@nospam.fr> wrote:
Le 11/09/2009 22:53, Stephane Legras-Decussy a écrit :
<ri...@apc.happyleptic.org> a écrit dans le message de news:
slrnhakq0v.an5.ri...@apc.happyleptic.org...
unsigned int a = 3232235530U;
pour moi c'est interdit de faire ça, ce nombre
ne rentre pas dans la plage garantie
de 0 à 65 535 ...
En quoi c'est interdit ?
C'est interdit si on cherche à écrire du code portable.
Si l'on doit se conformer strictement aux valeurs minimales de la norme
on ne programme plus grand chose.
Réponse idiote. On choisit le bon type, c'est tout. (ici, unsigned
long).
On 12 sep, 07:14, Richard Delorme wrote:Le 11/09/2009 22:53, Stephane Legras-Decussy a écrit :a écrit dans le message de news:unsigned int a = 3232235530U;pour moi c'est interdit de faire ça, ce nombre
ne rentre pas dans la plage garantie
de 0 à 65 535 ...
En quoi c'est interdit ?
C'est interdit si on cherche à écrire du code portable.
Si l'on doit se conformer strictement aux valeurs minimales de la norme
on ne programme plus grand chose.
Réponse idiote. On choisit le bon type, c'est tout. (ici, unsigned
long).
On 11 sep, 17:09, wrote:Petit exercice amusant :
comprendre pourquoi ce programme n'affiche pas deux fois la même valeur.
#include<stdio.h>
int main(void)
{
unsigned int a = 3232235530U;
float value = a;
printf("a=%.2f %.2fn", (float)a, value);
return 0;
}
Ca nous a bien occupé une demi heure aujourd'hui, j'espère que ça vous
amusera autant que nous.
Bah, moi, j'obtiens
a232235530.00 3232235530.00
Process returned 0 (0x0) execution time : 0.046 s
Press any key to continue.
parce que mes int font 32 bit...
Pour être portable C90 et éviter les
conversions douteuses et inutiles :
#include<stdio.h>
int main (void)
{
unsigned long a = 3232235530UL;
double value = a;
printf ("a=%.2f %.2fn", (double) a, value);
return 0;
}
On 11 sep, 17:09, ri...@apc.happyleptic.org wrote:
Petit exercice amusant :
comprendre pourquoi ce programme n'affiche pas deux fois la même valeur.
#include<stdio.h>
int main(void)
{
unsigned int a = 3232235530U;
float value = a;
printf("a=%.2f %.2fn", (float)a, value);
return 0;
}
Ca nous a bien occupé une demi heure aujourd'hui, j'espère que ça vous
amusera autant que nous.
Bah, moi, j'obtiens
a232235530.00 3232235530.00
Process returned 0 (0x0) execution time : 0.046 s
Press any key to continue.
parce que mes int font 32 bit...
Pour être portable C90 et éviter les
conversions douteuses et inutiles :
#include<stdio.h>
int main (void)
{
unsigned long a = 3232235530UL;
double value = a;
printf ("a=%.2f %.2fn", (double) a, value);
return 0;
}
On 11 sep, 17:09, wrote:Petit exercice amusant :
comprendre pourquoi ce programme n'affiche pas deux fois la même valeur.
#include<stdio.h>
int main(void)
{
unsigned int a = 3232235530U;
float value = a;
printf("a=%.2f %.2fn", (float)a, value);
return 0;
}
Ca nous a bien occupé une demi heure aujourd'hui, j'espère que ça vous
amusera autant que nous.
Bah, moi, j'obtiens
a232235530.00 3232235530.00
Process returned 0 (0x0) execution time : 0.046 s
Press any key to continue.
parce que mes int font 32 bit...
Pour être portable C90 et éviter les
conversions douteuses et inutiles :
#include<stdio.h>
int main (void)
{
unsigned long a = 3232235530UL;
double value = a;
printf ("a=%.2f %.2fn", (double) a, value);
return 0;
}
On 12 sep, 07:14, Richard Delorme wrote:Le 11/09/2009 22:53, Stephane Legras-Decussy a écrit :a écrit dans le message de news:unsigned int a = 3232235530U;pour moi c'est interdit de faire ça, ce nombre
ne rentre pas dans la plage garantie
de 0 à 65 535 ...
En quoi c'est interdit ?
C'est interdit si on cherche à écrire du code portable. C'est autorisé
si on impose un choix de plateformes avec des int à 32-bit...Si l'on doit se conformer strictement aux valeurs minimales de la norme
on ne programme plus grand chose.
Réponse idiote. On choisit le bon type, c'est tout. (ici, unsigned
long).
On 12 sep, 07:14, Richard Delorme <abu...@nospam.fr> wrote:
Le 11/09/2009 22:53, Stephane Legras-Decussy a écrit :
<ri...@apc.happyleptic.org> a écrit dans le message de news:
slrnhakq0v.an5.ri...@apc.happyleptic.org...
unsigned int a = 3232235530U;
pour moi c'est interdit de faire ça, ce nombre
ne rentre pas dans la plage garantie
de 0 à 65 535 ...
En quoi c'est interdit ?
C'est interdit si on cherche à écrire du code portable. C'est autorisé
si on impose un choix de plateformes avec des int à 32-bit...
Si l'on doit se conformer strictement aux valeurs minimales de la norme
on ne programme plus grand chose.
Réponse idiote. On choisit le bon type, c'est tout. (ici, unsigned
long).
On 12 sep, 07:14, Richard Delorme wrote:Le 11/09/2009 22:53, Stephane Legras-Decussy a écrit :a écrit dans le message de news:unsigned int a = 3232235530U;pour moi c'est interdit de faire ça, ce nombre
ne rentre pas dans la plage garantie
de 0 à 65 535 ...
En quoi c'est interdit ?
C'est interdit si on cherche à écrire du code portable. C'est autorisé
si on impose un choix de plateformes avec des int à 32-bit...Si l'on doit se conformer strictement aux valeurs minimales de la norme
on ne programme plus grand chose.
Réponse idiote. On choisit le bon type, c'est tout. (ici, unsigned
long).
candide, le 12/09/2009 a écrit :
Un fois admise cette précision de 24 bits, qui sera confirmée par la
consultation de FLT_RADIX et FLT_MANT_DIG, le comportement est tout à
fait prévisible. A partir de 2**24 et jusqu'à 2**25 - 1, on va perdre le
dernier bit. S'il est à 1, l'affichage du programme de l'OP fera
apparaître la différence. S'il est à 0, donc tout les nombres pairs,
rien ne se verra. A partir de 2**25, 2 bits seront concernés, donc seuls
les multiples de 4 seront indemnes. Et ainsi de suite.
(*) La norme n'impose pas grand chose, après une lecture en diagonale
très rapide de §5.2.4.2.2. Pour ce qui est de la mantisse, il est imposé
en float une représentation "sûre" des nombres de 6 chiffres en décimal.
Ce qui imposerait sauf erreur de ma part 20 digits (bits) si la base est
2. Et il doit exister un type qui représente de façon "sûre" des nombres
de 10 chiffres en décimal. D'où une mantisse de 32 bits si base 2.
(**) Contrairement aux entiers, les positifs et les négatifs sont très
symétriques pour les flottants.
(***) Bien entendu la réalité est plus complexe, et il faut bien voir
que ce bit qu'on gagne là, on le perdra ailleurs. En réalité un format
de flottant, et partant une FPU, est un truc imparfait, dangereux, mais
pragmatique et utile. Un règle de base de son utilisation est de tout
tenter pour l'éviter.6.3.1.3 Signed and unsigned integers
(...)
When a value of integer type is converted to a real floating type, if
the value being converted can be represented exactly in the new type,
it is unchanged. If the value being converted is in the range of
values that can be represented but cannot be represented exactly, the
result is either the nearest higher or nearest lower representable
value, chosen in an implementation-defined manner.
Dans l'exemple de l'OP, le comportement de value est sans ambiguité.
value est une variable float, la perte de précision se fait lors de son
initialisation est l'affichage est sans surprise.
Pour ce qui est du (float)a, de toute évidence a est converti en double
et affiché comme un double. D'ailleurs, selon la norme, printf() ne sait
afficher que des double. Le cast (float) est donc ignoré, il n'y a pas
de temporaire float. Je ne saurais dire avec certitude si ce
comportement est prévisible, il me semble qu'il y a régulièrement des
posts à ce sujet ici même. Disons qu'il ne m'étonne pas et que
l'affichage des flottants dans un programme au moins partiellement
portable est un truc qui me gonfle particulièrement. J'aurais tendance à
penser que le comportement peut changer d'un compilateur à l'autre, et
même - le cas est courant et bien chiant - d'une bibliothèque dynamique
à l'autre.
En bref, si on veut afficher le float, on fait un float avant le
printf() "et pi cé tou".
candide, le 12/09/2009 a écrit :
Un fois admise cette précision de 24 bits, qui sera confirmée par la
consultation de FLT_RADIX et FLT_MANT_DIG, le comportement est tout à
fait prévisible. A partir de 2**24 et jusqu'à 2**25 - 1, on va perdre le
dernier bit. S'il est à 1, l'affichage du programme de l'OP fera
apparaître la différence. S'il est à 0, donc tout les nombres pairs,
rien ne se verra. A partir de 2**25, 2 bits seront concernés, donc seuls
les multiples de 4 seront indemnes. Et ainsi de suite.
(*) La norme n'impose pas grand chose, après une lecture en diagonale
très rapide de §5.2.4.2.2. Pour ce qui est de la mantisse, il est imposé
en float une représentation "sûre" des nombres de 6 chiffres en décimal.
Ce qui imposerait sauf erreur de ma part 20 digits (bits) si la base est
2. Et il doit exister un type qui représente de façon "sûre" des nombres
de 10 chiffres en décimal. D'où une mantisse de 32 bits si base 2.
(**) Contrairement aux entiers, les positifs et les négatifs sont très
symétriques pour les flottants.
(***) Bien entendu la réalité est plus complexe, et il faut bien voir
que ce bit qu'on gagne là, on le perdra ailleurs. En réalité un format
de flottant, et partant une FPU, est un truc imparfait, dangereux, mais
pragmatique et utile. Un règle de base de son utilisation est de tout
tenter pour l'éviter.
6.3.1.3 Signed and unsigned integers
(...)
When a value of integer type is converted to a real floating type, if
the value being converted can be represented exactly in the new type,
it is unchanged. If the value being converted is in the range of
values that can be represented but cannot be represented exactly, the
result is either the nearest higher or nearest lower representable
value, chosen in an implementation-defined manner.
Dans l'exemple de l'OP, le comportement de value est sans ambiguité.
value est une variable float, la perte de précision se fait lors de son
initialisation est l'affichage est sans surprise.
Pour ce qui est du (float)a, de toute évidence a est converti en double
et affiché comme un double. D'ailleurs, selon la norme, printf() ne sait
afficher que des double. Le cast (float) est donc ignoré, il n'y a pas
de temporaire float. Je ne saurais dire avec certitude si ce
comportement est prévisible, il me semble qu'il y a régulièrement des
posts à ce sujet ici même. Disons qu'il ne m'étonne pas et que
l'affichage des flottants dans un programme au moins partiellement
portable est un truc qui me gonfle particulièrement. J'aurais tendance à
penser que le comportement peut changer d'un compilateur à l'autre, et
même - le cas est courant et bien chiant - d'une bibliothèque dynamique
à l'autre.
En bref, si on veut afficher le float, on fait un float avant le
printf() "et pi cé tou".
candide, le 12/09/2009 a écrit :
Un fois admise cette précision de 24 bits, qui sera confirmée par la
consultation de FLT_RADIX et FLT_MANT_DIG, le comportement est tout à
fait prévisible. A partir de 2**24 et jusqu'à 2**25 - 1, on va perdre le
dernier bit. S'il est à 1, l'affichage du programme de l'OP fera
apparaître la différence. S'il est à 0, donc tout les nombres pairs,
rien ne se verra. A partir de 2**25, 2 bits seront concernés, donc seuls
les multiples de 4 seront indemnes. Et ainsi de suite.
(*) La norme n'impose pas grand chose, après une lecture en diagonale
très rapide de §5.2.4.2.2. Pour ce qui est de la mantisse, il est imposé
en float une représentation "sûre" des nombres de 6 chiffres en décimal.
Ce qui imposerait sauf erreur de ma part 20 digits (bits) si la base est
2. Et il doit exister un type qui représente de façon "sûre" des nombres
de 10 chiffres en décimal. D'où une mantisse de 32 bits si base 2.
(**) Contrairement aux entiers, les positifs et les négatifs sont très
symétriques pour les flottants.
(***) Bien entendu la réalité est plus complexe, et il faut bien voir
que ce bit qu'on gagne là, on le perdra ailleurs. En réalité un format
de flottant, et partant une FPU, est un truc imparfait, dangereux, mais
pragmatique et utile. Un règle de base de son utilisation est de tout
tenter pour l'éviter.6.3.1.3 Signed and unsigned integers
(...)
When a value of integer type is converted to a real floating type, if
the value being converted can be represented exactly in the new type,
it is unchanged. If the value being converted is in the range of
values that can be represented but cannot be represented exactly, the
result is either the nearest higher or nearest lower representable
value, chosen in an implementation-defined manner.
Dans l'exemple de l'OP, le comportement de value est sans ambiguité.
value est une variable float, la perte de précision se fait lors de son
initialisation est l'affichage est sans surprise.
Pour ce qui est du (float)a, de toute évidence a est converti en double
et affiché comme un double. D'ailleurs, selon la norme, printf() ne sait
afficher que des double. Le cast (float) est donc ignoré, il n'y a pas
de temporaire float. Je ne saurais dire avec certitude si ce
comportement est prévisible, il me semble qu'il y a régulièrement des
posts à ce sujet ici même. Disons qu'il ne m'étonne pas et que
l'affichage des flottants dans un programme au moins partiellement
portable est un truc qui me gonfle particulièrement. J'aurais tendance à
penser que le comportement peut changer d'un compilateur à l'autre, et
même - le cas est courant et bien chiant - d'une bibliothèque dynamique
à l'autre.
En bref, si on veut afficher le float, on fait un float avant le
printf() "et pi cé tou".
Bah, moi, j'obtiens
a232235530.00 3232235530.00
Process returned 0 (0x0) execution time : 0.046 s
Press any key to continue.
parce que mes int font 32 bit... Pour être portable C90 et éviter les
conversions douteuses et inutiles :
#include <stdio.h>
int main (void)
{
unsigned long a = 3232235530UL;
double value = a;
printf ("a=%.2f %.2fn", (double) a, value);
return 0;
}
Bah, moi, j'obtiens
a232235530.00 3232235530.00
Process returned 0 (0x0) execution time : 0.046 s
Press any key to continue.
parce que mes int font 32 bit... Pour être portable C90 et éviter les
conversions douteuses et inutiles :
#include <stdio.h>
int main (void)
{
unsigned long a = 3232235530UL;
double value = a;
printf ("a=%.2f %.2fn", (double) a, value);
return 0;
}
Bah, moi, j'obtiens
a232235530.00 3232235530.00
Process returned 0 (0x0) execution time : 0.046 s
Press any key to continue.
parce que mes int font 32 bit... Pour être portable C90 et éviter les
conversions douteuses et inutiles :
#include <stdio.h>
int main (void)
{
unsigned long a = 3232235530UL;
double value = a;
printf ("a=%.2f %.2fn", (double) a, value);
return 0;
}
Je ne comprends pas votre approche quasi religieuse. Vous vous situez
systématiquement dans un contexte de code portable directement, sans
intervention du préprocesseur.
Je ne comprends pas votre approche quasi religieuse. Vous vous situez
systématiquement dans un contexte de code portable directement, sans
intervention du préprocesseur.
Je ne comprends pas votre approche quasi religieuse. Vous vous situez
systématiquement dans un contexte de code portable directement, sans
intervention du préprocesseur.
Qu'en pensez vous ?
Qu'en pensez vous ?
Qu'en pensez vous ?
Effectivement le résultat dépend du compilateur et/ou de l'architecture.
Je ne m'attendais pas à ça.
Et la question était donc : mais pourquoi donc le cast dans le printf
donne t-il le bon résultat ?
Stipulent que (double)(float)3232235530U devrait valoir
3232235520.00. Or dans notre cas il semble que gcc ait préféré,
étant donné le cast implicite en double, ignorer notre cast explicite
en float.
Effectivement le résultat dépend du compilateur et/ou de l'architecture.
Je ne m'attendais pas à ça.
Et la question était donc : mais pourquoi donc le cast dans le printf
donne t-il le bon résultat ?
Stipulent que (double)(float)3232235530U devrait valoir
3232235520.00. Or dans notre cas il semble que gcc ait préféré,
étant donné le cast implicite en double, ignorer notre cast explicite
en float.
Effectivement le résultat dépend du compilateur et/ou de l'architecture.
Je ne m'attendais pas à ça.
Et la question était donc : mais pourquoi donc le cast dans le printf
donne t-il le bon résultat ?
Stipulent que (double)(float)3232235530U devrait valoir
3232235520.00. Or dans notre cas il semble que gcc ait préféré,
étant donné le cast implicite en double, ignorer notre cast explicite
en float.
le code suivant ne fait aucune conversion en double
(...)
if ((float) a - value > 5.0)
le code suivant ne fait aucune conversion en double
(...)
if ((float) a - value > 5.0)
le code suivant ne fait aucune conversion en double
(...)
if ((float) a - value > 5.0)