OVH Cloud OVH Cloud

comparaison de flottants

209 réponses
Avatar
Emmanuel
bonjour tout le monde,

une question de vrai débutant :

Avec le programme essai.c suivant

int main(void) {
return ((1.7 + 0.1) == 1.8) ? 1 : 0;
}

j'obtiens :

$ gcc -Wall -o essai essai.c; ./essai; echo $?
1

Avec le programme essai.c suivant

int main(void) {
float x;
x = 1.7;
return ((x + 0.1) == 1.8) ? 1 : 0;
}

j'obtiens :

$ gcc -Wall -o essai essai.c; ./essai; echo $?
0

Pourtant, le programme

#include <stdio.h>
int main(void) {
float x;
x = 1.7;
printf("%f et %f\n", 1.7 + 0.1, x + 0.1);
}

affiche :
1.800000 et 1.800000

Apparremment, 1.7+0.1 et x+0.1 sont égaux ; j'imagine qu'il s'agit d'un
problème de représentation des flottants en machine mais j'aimerais bien
avoir une confirmation ou une infirmation (et une explication, si possible).

Merci par avance.

Emmanuel

10 réponses

Avatar
JKB
Le 07-04-2010, ? propos de
Re: comparaison de flottants,
Vincent Lefevre ?crivait dans fr.comp.lang.c :
Dans l'article <4bbc320c$0$22387$,
Samuel DEVULDER écrit:

Vincent Lefevre a écrit :
> Pas essayé LCC, mais pour TCC, c'est faux. Sous Linux/x86_64:
>
> ypig:.../testcases/c-impl> tcc types.c
> ypig:.../testcases/c-impl> ./a.out
> [...]
> --> long / unsigned long
> LONG_MIN = - 2^63 = -9223372036854775808
> LONG_MAX = 2^63 - 1 = 9223372036854775807
> ULONG_MAX = 2^64 - 1 = 18446744073709551615
> sizeof(long) = 8, signed
> sizeof(unsigned long) = 8, unsigned
> [...]



Et alors? TCC sous DOS, ou ARM a aussi des longs à 32bit et c'est pour
cela que je dis que MSVC n'est pas le seul à avoir un long à 32bit.



ARM n'est pas un processeur 64 bits!!!

[...]
ce qu'il se passe, dans cette partie c'est on remplace "long" par un int
ou long long (64bits). Pour la target X86_64 (linux), c'est 64bits et
*partout* ailleurs (dos, arm, C67, cil) c'est du 32bits.



Parce que pour le reste, il ne s'agit pas de processeurs 64 bits.

Pour l'instant les unixoides ont fait la bascule sizeof(long)==8, le
reste du monde (et il y en a pas mal) ont encore une ABI assez ancrée
32bits.



Mais à par les Unix (incluant Mac OS X) et MS Windows, qu'y a-t-il
tournant sur processeur 64 bits?



OpenVMS sur Alpha ou IA64 ?

JKB

--
Le cerveau, c'est un véritable scandale écologique. Il représente 2% de notre
masse corporelle, mais disperse à lui seul 25% de l'énergie que nous
consommons tous les jours.
Avatar
Vincent Lefevre
Dans l'article <4bbc2c39$0$24223$,
Samuel DEVULDER écrit:

Vincent Lefevre a écrit :
> Dans l'article <4bbb7cce$0$18404$,
> Samuel DEVULDER écrit:
>
>> Ca veut dire quoi "sale" pour toi?
>
> Utiliser des int implicites, par exemple.

Pourquoi? Parce que C99 l'interdit?



Non, parce que ce qui est implicite est souvent sale (mais à voir
au cas par cas).

On te parles justement de regarder ce qui se faisait avant.



Justement, je n'ai pas attendu C99 pour ne *pas* utiliser les types
implicites dans mes programmes!

--
Vincent Lefèvre - Web: <http://www.vinc17.net/>
100% accessible validated (X)HTML - Blog: <http://www.vinc17.net/blog/>
Work: CR INRIA - computer arithmetic / Arénaire project (LIP, ENS-Lyon)
Avatar
Samuel DEVULDER
Vincent Lefevre a écrit :

Et alors? TCC sous DOS, ou ARM a aussi des longs à 32bit et c'est pour
cela que je dis que MSVC n'est pas le seul à avoir un long à 32bit.



ARM n'est pas un processeur 64 bits!!!



Quel rapport? J'ai même du sizeof(long long)==8 sur du cpu 8/16bit. Ca
n'invalide pas ce que je dis depuis le début: MSVC n'est pas seul à
avoir sizeof(long)==4.

sam.
Avatar
Jean-Marc Bourguet
Samuel DEVULDER writes:

Antoine Leca a écrit :

Il reste Microsoft qui eux sont restés sur long2 bits, tout en
expliquant qu'il ne faut pas utiliser les types de base (ni printf).



Oh il n'y a pas que MSVC qui a des long à 32bits.. TCC, et LCC sont aussi
comme cela.

Il faudra que vérifie CodeWarrior mais ca ne m'étonnerait pas
non plus (et pourtant le CPU cible est un 64bits...)



C'est le genre de choses pour lesquelles il y a un intérêt certain à suivre
le choix de l'OS. Je considèrerais comme un bug le fait de cibler Windows
et d'avoir des long sur 64 bits ou de cibler un Unix 64 bits (y compris
MacOS X) et de ne pas avoir des longs sur 64 bits. (Sauf naturellement s'il
s'agit d'un mode conçu pour faciliter le portage d'applications pour
l'autre modèle).

Par ailleurs, je trouve que dans des environnements évolutifs, c'est
effectivement un soucis d'utiliser les types de base dans la mesure où
rien de garanti la taille en bit. Les typedefs de <stdint.h> sont plutôt
une bonne façon de se prémunir du fait que la taille du long int varie au
cours du temps et entre les systèmes.



Oui et non. Les types avec des tailles absolues sont d'après moi une
fausse sécurité -- hors interface avec l'extérieur et encore. Les types
avec des tailles minimales ne sont que légèrement plus utiles. uintptr_t
et (u)intmax_t sont au final les seuls que j'utilise réellement, parce
qu'ils sont définis par une propriété et non une taille.

J'ai plutôt tendance à considérer qu'il y a un abus de ces typedefs "de
portabilité" (et d'autres définis par les bibliothèques), utilisés de
manière inconstante, en supposant souvent qu'ils sont identiques quand rien
ne l'impose. En pratique ils n'apportent souvent rien d'autre qu'une
incitation à sous-estimer le travail nécessaire pour faire fonctionner
l'application sur la cible ("il n'y a qu'à changer les typedefs").

A+

--
Jean-Marc
FAQ de fclc: http://www.levenez.com/lang/c/faq
Site de usenet-fr: http://www.usenet-fr.news.eu.org
Avatar
Vincent Lefevre
Dans l'article ,
JKB écrit:

Le 07-04-2010, ? propos de
Re: comparaison de flottants,
Vincent Lefevre ?crivait dans fr.comp.lang.c :
> Dans l'article <4bbc320c$0$22387$,
> Samuel DEVULDER écrit:


[...]
>> Pour l'instant les unixoides ont fait la bascule sizeof(long)==8, le
>> reste du monde (et il y en a pas mal) ont encore une ABI assez ancrée
>> 32bits.
>
> Mais à par les Unix (incluant Mac OS X) et MS Windows, qu'y a-t-il
> tournant sur processeur 64 bits?

OpenVMS sur Alpha ou IA64 ?



Donc contrairement à ce qu'affirme Samuel, ce n'est pas le reste
du monde qui utilise une ABI 32 bits.

http://h71000.www7.hp.com/doc/82final/6673/6673pro.html

OpenVMS on Alpha systems is deliberately ambiguous about the data
model in use: many programs are compiled using what appears to be an
ILP32 model, yet most of the system operates as though using either
a P64 or LP64 model. The sign extension rules for integer parameters
play a key role in making this more or less transparent. OpenVMS I64
preserves this characteristic, while the Itanium architecture
conventions define a pure LP64 data model.

--
Vincent Lefèvre - Web: <http://www.vinc17.net/>
100% accessible validated (X)HTML - Blog: <http://www.vinc17.net/blog/>
Work: CR INRIA - computer arithmetic / Arénaire project (LIP, ENS-Lyon)
Avatar
JKB
Le 07-04-2010, ? propos de
Re: comparaison de flottants,
Vincent Lefevre ?crivait dans fr.comp.lang.c :
Dans l'article ,
JKB écrit:

Le 07-04-2010, ? propos de
Re: comparaison de flottants,
Vincent Lefevre ?crivait dans fr.comp.lang.c :
> Dans l'article <4bbc320c$0$22387$,
> Samuel DEVULDER écrit:


[...]
>> Pour l'instant les unixoides ont fait la bascule sizeof(long)==8, le
>> reste du monde (et il y en a pas mal) ont encore une ABI assez ancrée
>> 32bits.
>
> Mais à par les Unix (incluant Mac OS X) et MS Windows, qu'y a-t-il
> tournant sur processeur 64 bits?



OpenVMS sur Alpha ou IA64 ?



Donc contrairement à ce qu'affirme Samuel, ce n'est pas le reste
du monde qui utilise une ABI 32 bits.

http://h71000.www7.hp.com/doc/82final/6673/6673pro.html

OpenVMS on Alpha systems is deliberately ambiguous about the data
model in use: many programs are compiled using what appears to be an
ILP32 model, yet most of the system operates as though using either
a P64 or LP64 model. The sign extension rules for integer parameters
play a key role in making this more or less transparent. OpenVMS I64
preserves this characteristic, while the Itanium architecture
conventions define a pure LP64 data model.



Et dans le cas OpenVMS, ça s'explique facilement (et on ne parle pas
encore des formats de flottants ;-) ).

JKB

--
Le cerveau, c'est un véritable scandale écologique. Il représente 2% de notre
masse corporelle, mais disperse à lui seul 25% de l'énergie que nous
consommons tous les jours.
Avatar
Samuel DEVULDER
Vincent Lefevre a écrit :
Dans l'article <4bbc2c39$0$24223$,
Samuel DEVULDER écrit:

Vincent Lefevre a écrit :
Dans l'article <4bbb7cce$0$18404$,
Samuel DEVULDER écrit:

Ca veut dire quoi "sale" pour toi?


Utiliser des int implicites, par exemple.





Pourquoi? Parce que C99 l'interdit?



Non, parce que ce qui est implicite est souvent sale (mais à voir
au cas par cas).



Rappel:

Dialogue:
Perso1 => Oui mais l'implicite c'est pas-bien(tm)!



On vient de trouver qui était "Perso1".

On te parles justement de regarder ce qui se faisait avant.



Justement, je n'ai pas attendu C99 pour ne *pas* utiliser les types
implicites dans mes programmes!



Tu devrais aller voir de voir du coté d'ADA (et son cheval *sic*), ou
mieux, essaye de voir du coté caml, haskell etc..

sam.
Avatar
Samuel DEVULDER
Vincent Lefevre a écrit :

Donc contrairement à ce qu'affirme Samuel, ce n'est pas le reste
du monde qui utilise une ABI 32 bits.



Je n'ai pas dit cela. J'ai dit "il n'y a pas que MSVC" qui soit resté
avec sizeof(long)==4. N'inverse pas mes propos STP (déjà que tu inverses
la définition de strtod et printf..)

sam (renversant!)
Avatar
Jean-Marc Bourguet
Samuel DEVULDER writes:

Vincent Lefevre a écrit :
Dans l'article <4bbb7cce$0$18404$,
Samuel DEVULDER écrit:

Ca veut dire quoi "sale" pour toi?



Utiliser des int implicites, par exemple.



Pourquoi? Parce que C99 l'interdit?



Je crois que tu renverses la causalité. C99 l'interdit, malgré le fait que
le problème de compatibilité sont pris très au sérieux lors de la
normalisation, parce que c'est quasiment universellement considéré
comme une pratique non recommandable, héritage de B, langage non typé,
laissés là pour faciliter le portage de programme en B et ayant survécu
bien trop longtemps à son utilité.

A+

--
Jean-Marc
FAQ de fclc: http://www.levenez.com/lang/c/faq
Site de usenet-fr: http://www.usenet-fr.news.eu.org
Avatar
Vincent Belaïche
Bonjour,

En toute rigueur en effet quand on parle de nombre binaire, ou de nombre
décimal, on fait référence à ses propriétés mathématiques et non à sa
représentation textuelle, c'est à dire qu'on parle de sa base numération
en mémoire.

Autre chose, lorsqu'on parle de nombre à virgule flottante intervient
aussi la base de logarithme utilisée pour l'exposant. Je pense que dans
la référence cité le "binary" dans "binary exponent part" faisait
référence à cela et non au format de représentation en mémoire/en texte
comme la discussion qui vient d'avoir lieu a pu le laissé entendre. On
peut donc résumer l'ensemble comme cela :

| format | %e, %g, %f | %a | en mémoire |
|------------------------------------+------------+----+------------|
| base de numération de l'exposant | 10 | 10 | 2 |
| base de logarithme de l'exposant | 10 | 2 | 2 |
| base de numération du significande | 10 | 16 | 2 |


Vincent.

Samuel DEVULDER a écrit :
Vincent Lefevre a écrit :
Dans l'article <4bbb6912$0$16031$,
Samuel DEVULDER écrit:

Vincent Lefevre a écrit :
Dans l'article <4bbb03ab$0$8366$,
Samuel DEVULDER écrit:

Désolé. Sur
http://www.open-std.org/JTC1/SC22/wg14/www/docs/n1124.pdf je n'ai
pas trouvé "binary exponent part" dans la description de printf


Ce n'était pas dans la description de printf (le format en question
revient à plusieurs endroits dans la norme, pas seulement avec
printf).





Heu je sais pas.. on parle de printf, aussi je regarde la spec de ce
dernier? Pas toi? Tu vas voir de quel coté toi, strod? atoi? rand?
Quelle blague!



Tu demandais ce que voulait dire "exposant binaire". Je te donne



Non.

simplement une référence où ce terme est employé! Et quitte à
utiliser une spec, autant choisir celle qui utilise les termes
adéquats.



Tu as loupé aussi une référence de "binary exponent" dans la spec
fortran 90 alors aussi pendant qu'on y est. Quand on te demande où
comment on se rend à la rue de la poste à Albi, toi tu réponds au sujet
de la rue de la poste à Bordeaux. Super!

Si tu ne veux pas qu'on réponde à tes questions, n'en pose pas!



Hum... Ridicule.

sam.