Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Division et arrondi

54 réponses
Avatar
lhommedumatch
J'ai ce programme:
#include <iostream>
#include <math.h>

int main()
{
float x=3D10.0;
float y=3D1.0;
float scale=3D0.1;
int res;

res =3D int (x/scale);
std::cout << res << std::endl;
return 0;
}

Si je le compile avec:
version gcc 4.1.2 20071124 (Red Hat 4.1.2-42)
sur une machine 32bits j'obtiens 99
sur une machine 64bits j'obtiens 100

Quelqu'un pourrait m'=E9clairer.
Merci

10 réponses

2 3 4 5 6
Avatar
Kojak
Le Fri, 27 Mar 2009 13:54:16 +0000 (UTC),
Vincent Lefevre a écrit :

Dans l'article ,
Kojak écrit:
> Le Thu, 26 Mar 2009 17:51:22 +0000 (UTC),
> Vincent Lefevre a écrit :
> > Attention, il faut alors stocker tous les résultats intermé diaires
> > dans des variables temporaires, e.g.
> Tout à fait.

En fait, j'ai vérifié tout à l'heure (pas sur ce code, mai s sur un
autre code très simple, indépendamment de cette enfilade): cela est
nécessaire avec un gcc 3.4, mais avec un gcc 4.1, les variables
temporaires n'étaient pas nécessaires, i.e. avec -ffloat-store, seul
gcc 3.4 sans variables temporaires pour les résultats intermédi aires
ne donnait pas le résultat voulu. Cependant, la page man de gcc 4.1
[...]



Sur x86 ? Parce que je viens d'essayer avec :

-------8<--------------8<--------------8<--------------8<-------
cat <<EOF >peekaboo.c
#include <stdio.h>

int main (void)
{
float f, x, y, z, u = 1.0, v = 0.1;

f = u / v / v / v;
printf ("Les flottants c'est tabou = %fn", f);

x = u / v;
y = x / v;
z = y / v;
printf ("On en viendra tous à bout = %fn", z);

return 0;
}
EOF
gcc -W -Wall -m32 -o peekaboo peekaboo.c
gcc -W -Wall -m32 -ffloat-store -o peekaboo_store peekaboo.c
-------8<--------------8<--------------8<--------------8<-------

Et, sauf erreur, j'obtiens toujours, sans '-ffloat-store' :

Les flottants c'est tabou = 999.999939
On en viendra tous à bout = 1000.000000

et avec '-ffloat-store' :

Les flottants c'est tabou = 1000.000000
On en viendra tous à bout = 1000.000000

Et ce, quelques soient les versions. Tout au moins, jusqu'à la
version 4.3.

Surpris, je suis !

--
Jacques.
Avatar
Vincent Lefevre
Dans l'article ,
Kojak écrit:

Le Fri, 27 Mar 2009 13:54:16 +0000 (UTC),
Vincent Lefevre a écrit :



> En fait, j'ai vérifié tout à l'heure (pas sur ce code, mais sur un
> autre code très simple, indépendamment de cette enfilade): cela est
> nécessaire avec un gcc 3.4, mais avec un gcc 4.1, les variables
> temporaires n'étaient pas nécessaires, i.e. avec -ffloat-store, seul
> gcc 3.4 sans variables temporaires pour les résultats intermédiaires
> ne donnait pas le résultat voulu. Cependant, la page man de gcc 4.1
> [...]



Sur x86 ?



Oui.

et avec '-ffloat-store' :



Les flottants c'est tabou = 1000.000000
On en viendra tous à bout = 1000.000000



ble:~> gcc-3.3 -W -Wall -m32 -ffloat-store -o peekaboo_store peekaboo.c
ble:~> ./peekaboo_store
Les flottants c'est tabou = 999.999939
On en viendra tous à bout = 1000.000000
ble:~> gcc-3.4 -W -Wall -m32 -ffloat-store -o peekaboo_store peekaboo.c
ble:~> ./peekaboo_store
Les flottants c'est tabou = 999.999939
On en viendra tous à bout = 1000.000000

Ce sont les paquets Debian gcc-3.3 1:3.3.6-15 et gcc-3.4 3.4.6-5
respectivement.

--
Vincent Lefèvre - Web: <http://www.vinc17.org/>
100% accessible validated (X)HTML - Blog: <http://www.vinc17.org/blog/>
Work: CR INRIA - computer arithmetic / Arenaire project (LIP, ENS-Lyon)
Avatar
Marc Boyer
On 2009-03-27, Antoine Leca wrote:
Le 27/03/2009 15:53Z, Marc Boyer écrivit :
Et oui, l'incompétence...


[...]
autant écrire du C et le compiler avec un compilo C++ montre
une incompétence importante.



Es-tu sûr ? Ai-je bien compris ta remarque ?
Je suis totalement incompétent en C++, domaine où je me borne à essayer
de comprendre petit à petit le bouquin^W pavé de Stroustrup, mais
d'après ce dernier cette démarche n'est pas aussi stupide que cela, un
des objectifs importants de C++ étant justement de pouvoir récupérer le
code C existant, il en découle donc que du code C « raisonnable » doit
pouvoir être recompilé en C++ sans quasiment aucun changement.



C'est tout le problème de "raisonnable" et du "quasiment".
Il existe un certain nombre d'incohérences entre C et C++, je ne me souviens
pas de toutes. sizeof('a') en est une.
En cherchant un peu sur le net, il y a aussi le problème du
const int i=0;
qui est extern en C et static en C++
Il y a aussi les sizeof d'enum.

Rien que de petites subtilités, qui si elles donnent lieu à bug,
doivent être super amusantes à aller dénicher.

Bon, après, pour tempérer mon propos, comme le respect d'une norme
sert surtout à la portabilité, et qu'un drivers Windows ne doit
avoir d'exigence de portabilité que Win* / VC++, finalement, ce
qui importe surtout, ce sont les tests unitaires sur la plateforme...

Bien évidemment, c'est complètement différent de la démarche qui
consisterait à franchir le 49e parallèle (ou l'Atlantique) et écrire
tout en C++, mais on en est pas là dans le cas de Pierre (je pense qu'un
driver Windows peut difficilement être écrit en C++, cela demanderait
une infrastructure importante).



Je ne sais pas.
En embarqué avionique et spacial civil, on utilise un sous-ensemble
de C, et on décrit quelles parties de C sont interdites (souvent
une grosse part d'ailleurs: pointeurs entre autre).
On peut décider de faire un driver en C++ en banissant toute une
partie qui paraît inadaptée (virtual, template, héritage).

Aussi si utiliser un compilo C++ sur du code C me paraît raisonnable, le
contraire, c'est-à-dire manipuler des choses C++ dans un environnement
C, me paraît [censuré].



Un compilo C++ sur du code C, pour la compil, sans problème.
Pour la génération de code, je ne vois pas l'intérêt.

Marc Boyer
--
Au XXIème siècle, notre projet de société s'est réduit
à un projet économique...
Avatar
Kojak
Le Mon, 30 Mar 2009 00:25:04 +0000 (UTC),
Vincent Lefevre a écrit :

ble:~> gcc-3.3 -W -Wall -m32 -ffloat-store -o peekaboo_store
peekaboo.c ble:~> ./peekaboo_store
Les flottants c'est tabou = 999.999939
On en viendra tous à bout = 1000.000000
ble:~> gcc-3.4 -W -Wall -m32 -ffloat-store -o peekaboo_store
peekaboo.c ble:~> ./peekaboo_store
Les flottants c'est tabou = 999.999939
On en viendra tous à bout = 1000.000000

Ce sont les paquets Debian gcc-3.3 1:3.3.6-15 et gcc-3.4 3.4.6-5
respectivement.



Bon, j'ai installé et vérifié avec la version 3.4.6 et, apr ès moult
investigations, il appert que l'option -ffloat-store ne sert à rien !
On obtient strictement le même code avec ou sans l'option. Bref, cette
version du compilateur est vermoulue.

Sinon, à défaut du tout venant, on peut se risquer sur le bizarre.
Bref, on peut s'en sortir en positionnant manu militari les modes
de calcul du FPU, voire, au pire, en gérant directement, mais bon...

-------8<--------------8<--------------8<--------------8<-------
#include <stdio.h>

int main (void)
{
float f, u = 1.0, v = 0.1;
float x = 10, y = 2;
volatile unsigned short int control, status;

printf
("vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvn");

asm volatile ("finit");
printf ("=> Reset FPUn");
asm volatile ("fstsw %0"::"m" (*&status));
printf ("Statut : %xn", status);
asm volatile ("fstcw %0"::"m" (*&control));
printf ("Mot de contrôle actuel : %xn", control);
f = u / v / v / v;
printf ("%f / %f / %f / %f = %fn", u, v, v, v, f);
asm volatile ("fstsw %0"::"m" (*&status));
printf ("Statut : %xn", status);

printf
("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~n");

asm volatile ("finit");
printf ("=> Reset FPUn");
asm volatile ("fstsw %0"::"m" (*&status));
printf ("Statut : %xn", status);
control = 0x007f;
asm volatile ("fldcw %0"::"m" (*&control));
printf ("Mot de contrôle positionné à : %xn", control);
f = u / v / v / v;
printf ("%f / %f / %f / %f = %fn", u, v, v, v, f);
asm volatile ("fstsw %0"::"m" (*&status));
printf ("Statut : %xn", status);

printf
("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~n");

asm volatile ("finit");
printf ("=> Reset FPUn");
asm volatile ("fstsw %0"::"m" (*&status));
printf ("Statut : %xn", status);
control = 0x037f;
asm volatile ("fldcw %0"::"m" (*&control));
printf ("Mot de contrôle positionné à : %xn", control);
f = x / y;
printf ("%f / %f = %fn", x, y, f);
asm volatile ("fstsw %0"::"m" (*&status));
printf ("Statut : %xn", status);

printf
("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^n");

return 42;
}
-------8<--------------8<--------------8<--------------8<-------

--
Jacques.
Avatar
Vincent Lefevre
Dans l'article ,
Kojak écrit:

Bon, j'ai installé et vérifié avec la version 3.4.6 et, après moult
investigations, il appert que l'option -ffloat-store ne sert à rien !
On obtient strictement le même code avec ou sans l'option. Bref, cette
version du compilateur est vermoulue.



Essaie d'ajouter l'option -mfpmath87 (ton compilo compile peut-être
en SSE2 par défaut).

--
Vincent Lefèvre - Web: <http://www.vinc17.org/>
100% accessible validated (X)HTML - Blog: <http://www.vinc17.org/blog/>
Work: CR INRIA - computer arithmetic / Arenaire project (LIP, ENS-Lyon)
Avatar
Vincent Lefevre
Dans l'article <20090327140413$,
Vincent Lefevre <vincent+ écrit:

Tu peux voir



http://gcc.gnu.org/bugzilla/show_bug.cgi?id23



Pour info, il y a eu du nouveau cette nuit.

Nouveau patch de Joseph S. Myers:

http://gcc.gnu.org/bugzilla/show_bug.cgi?id23#c126

Cf aussi http://gcc.gnu.org/bugzilla/show_bug.cgi?id23#c127 où
Joseph S. Myers dit: "Right now, -ffloat-store checks are scattered
about the optimizers and it seems unlikely that -ffloat-store really
implements any form of predictable semantics now". Donc mieux vaut
utiliser la nouvelle option -fexcess-precision=standard du futur
gcc 4.5 (implémentée par le patch en question). Noter que -stdÉ9
doit activer cette option.

--
Vincent Lefèvre - Web: <http://www.vinc17.org/>
100% accessible validated (X)HTML - Blog: <http://www.vinc17.org/blog/>
Work: CR INRIA - computer arithmetic / Arenaire project (LIP, ENS-Lyon)
Avatar
Kojak
Le Mon, 30 Mar 2009 10:43:48 +0000 (UTC),
Vincent Lefevre a écrit :

Dans l'article ,
Kojak écrit:

> Bon, j'ai installé et vérifié avec la version 3.4.6 et, après moult
> investigations, il appert que l'option -ffloat-store ne sert à
> rien ! On obtient strictement le même code avec ou sans l'option.
> Bref, cette version du compilateur est vermoulue.

Essaie d'ajouter l'option -mfpmath87 (ton compilo compile peut-ê tre
en SSE2 par défaut).



Déjà testé avec. :-) De toute façon, avec les extension s SSE*,
ça passe sans problème...

Donc, je suis bien en 387, pas un iota de SSE*. Avec ou sans
l'option -mfpmath87, même résultat, l'option -ffloat-store
est sans effet. Même code à l'arrivée. J'ai vérifià © aussi le
code assembleur généré.

Bref, j'en reviens toujours à la conclusion que c'est un bug
du compulateur.

--
Jacques.
Avatar
Jean-Marc Bourguet
Marc Boyer writes:

Il existe un certain nombre d'incohérences entre C et C++, je ne me
souviens pas de toutes.



Il ne faut pas exagerer l'importance pratique de ces differences.

Je crois avoir deja eu l'occasion de dire que je travaille sur un programme
historiquement ecrit en C, qui a eu ensuite des parties ecrites en C++ et
qui a decide par la suite de compiler en C++ des choses ecrites au depart
en C. De cette conversion, mon impression -- j'ai pas particulierement
travailler sur la conversion -- est qu'on a a peu pres plus de risque de
trouver un bug du compilateur que du trouver un bug introduit par le fait
que le resultat a une semantique differente en C et en C++ (si j'ai bonne
memoire, on a eu plus d'occurences du premier cas que du second, mais pas
significativement plus). J'ai pas eu une bonne vision du nombre de vrais
bugs detectes par le compilateur C++ que lint et les compilateurs C ne
signalaient pas.

En passant, certains sont en train de faire modifier le code de gcc pour
qu'il soit compilable en C++ et en C; avec comme effet qu'ils ont ajoute la
possibilite d'avoir un warning sur certaines differences quand on compile
en C.

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
Antoine Leca
Le 30/03/2009 08:24Z, Marc Boyer écrivit :
On 2009-03-27, Antoine Leca wrote:
Le 27/03/2009 15:53Z, Marc Boyer écrivit :
autant écrire du C et le compiler avec un compilo C++ montre
une incompétence importante.


des objectifs importants de C++ étant justement de pouvoir récupérer le
code C existant, il en découle donc que du code C « raisonnable » doit
pouvoir être recompilé en C++ sans quasiment aucun changement.



C'est tout le problème de "raisonnable" et du "quasiment".
Il existe un certain nombre d'incohérences entre C et C++, je ne me souviens
pas de toutes. sizeof('a') en est une.


<snip>

Mmmm. Encore une fois, j'y connais quasi rien à C++ donc je ne veux
surtout pas passer pour une référence, mais dans le bouquin de
Stroustrup (et de mémoire, ça y était déjà dans la version que j'ai lue
en 1984 et qui m'a dégouté de C++ pour un gros bail... fin de la
parenthèse) il y a une annexe qui décrit les différences entre les deux
languages, cette annexe n'est pas bien épaisse, et il me semble que les
programmeurs (sérieux) en C devraient la connaître, au moins dans les
grandes lignes, histoire de savoir où leur code peut pécher.

Dans la pratique, on a les différences de nommages (et il y a export"C"
qui est fait pour), le type de NULL et quelques variations du même
genre, l'histoire du type de 'a' qui d'après ce que j'ai compris, sert
surtout à détecter le langage du compilateur :^), et dans les trucs plus
gênants, les utilisations de malloc() et le destin des const globales.


Rien que de petites subtilités, qui si elles donnent lieu à bug,
doivent être super amusantes à aller dénicher.



Bah oui, un peu comme tous les bogues subtils. Ce qui est le lot
quotidien des programmeurs, et qui plus est la partie *intéressante*
(parce que les corrections répétitives de bogues idiots, je ne trouve
personnellement pas cela amusant du tout.)
En plus, une fois qu'un programmeur s'est fait prendre à un bogue
subtil, il ne fera pas deux fois l'erreur ; je t'accorde ici que cela
génère un coût qui sera multiplié par le nombre de programmeurs
impliqués, car cet apprentissage sera propre à chacun et donc chaque
programmeur va potentiellement tomber dans le même piège, à moins
d'avoir des règles de développement qui préviennent, et là je m'en remet
aux spécialistes (pour résumer le long paragraphe à leur intention,
est-ce que dans les normes internes de développement vous avez des
règles qui assurent la compatibilité C/C++ ?)

Et oui, j'ai bien lu le message de Jean-Marc à propos de GCC. Qui me
paraît être dans la même ligne.


Antoine
Avatar
Marc Boyer
On 2009-03-30, Jean-Marc Bourguet wrote:
Marc Boyer writes:

Il existe un certain nombre d'incohérences entre C et C++, je ne me
souviens pas de toutes.



Il ne faut pas exagerer l'importance pratique de ces differences.



J'ai donné des exemples, en effet, ce n'est pas énorme.

Je crois avoir deja eu l'occasion de dire que je travaille sur un programme
historiquement ecrit en C, qui a eu ensuite des parties ecrites en C++ et
qui a decide par la suite de compiler en C++ des choses ecrites au depart
en C. De cette conversion, mon impression -- j'ai pas particulierement
travailler sur la conversion -- est qu'on a a peu pres plus de risque de
trouver un bug du compilateur que du trouver un bug introduit par le fait
que le resultat a une semantique differente en C et en C++ (si j'ai bonne
memoire, on a eu plus d'occurences du premier cas que du second, mais pas
significativement plus).



La démarche est, je pense, un peu différente de celle d'un simple
commentaire comme mis dans un entête. J'imagine (mais je peux me tromper),
qu'avant de considérer qu'un code C devient un code C++, on se renseigne
sur les différences entre les deux langages, et on regarde un peu
son code voire s'il utilise les constructions incriminées. Non ?

Il y a, de mon point de vue, une différence entre dire "je fais du C
mais je compile avec un compilo C++ parce que je préfères ses warnings",
et "ce code C, considérons le à partir d'aujourd'hui comme un code
C++, quels sont les impacts ?".

En passant, certains sont en train de faire modifier le code de gcc pour
qu'il soit compilable en C++ et en C; avec comme effet qu'ils ont ajoute la
possibilite d'avoir un warning sur certaines differences quand on compile
en C.



C'est à dire, un message du genre "Warning: this construction has
a different semantics in C and C++" ?

Marc Boyer
--
Au XXIème siècle, notre projet de société s'est réduit
à un projet économique...
2 3 4 5 6