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

1 2 3 4 5
Avatar
Kojak
Le Thu, 26 Mar 2009 17:51:22 +0000 (UTC),
Vincent Lefevre a écrit :

Dans l'article ,
Kojak écrit:

> Essaye avec l'option "-ffloat-store", ça peut aider...

Attention, il faut alors stocker tous les résultats intermédiai res
dans des variables temporaires, e.g.

[...]



Tout à fait.

Mais attention, ça ne règle pas le problème du double arro ndi, donc
il peut y avoir encore des différences.



Absolument, ça ne règle évidemment pas tous les problèm es.

Cela dit, il risque de "flotter" un moment dans les affres de
l'approximation, s'il n'a pas l'habitude de jouer avec... les
nombres flottants. Mais bon, à sa décharge, il convient de
rappeler que ce n'est pas, non plus, une mince affaire. Affaire,
d'ailleurs, plus en rapport avec le domaine de la mathématique
que celle de l'informatique "ordinaire".

--
Jacques.
Avatar
Jean-Marc Bourguet
Vincent Lefevre <vincent+ writes:

Voilà, ce n'est pas tout, mais il faut que je termine de relire
le livre qu'on est en train d'écrire dans notre équipe, qui va
justement parler de tous ces problèmes et de plein d'autres choses
sur l'arithmétique virgule flottante.



Tu l'annonceras ici STP (ou directement par mail -- mon adresse
est valide -- si tu crains qu'on t'accuse de spammer)?

Merci

--
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 27/03/2009 02:58Z, Vincent Lefevre écrivit :
Dans l'article <gqgg2j$tug$,
Antoine Leca écrit:

Le 25/03/2009 11:14Z, lhommedumatch écrivit :
float scale=0.1;
res = int (x/scale);
sur une machine 32bits j'obtiens 99
sur une machine 64bits j'obtiens 100

Quelqu'un pourrait m'éclairer.





24 est pair et 63 est impair (c'est à l'envers, hein).
Et 1/5 en base 2 a un motif de répétition de 2 bits.





On dirait que je n'avais pas les yeux en face des trous...
D'où les corrections suivantes :
- c'est évidemment 8/5 (p-4)
- le motif de répétition est sur 4 bits (c'est 1,_1001_)
- 23 est congruent à 3 (et 0,11 devrait être arrondi à 1)
- 63 est aussi congruent à 3
- 52 est congruent à 0, et 0,1001 devrait lui aussi être arrondi par
excès à 1 (avec une erreur proportionnellement plus importante)

Autrement dit, ce que j'indiquais n'est pas la bonne raison.


D'autre part, il n'est pas clair si le 0.1 (double précision, sauf
éventuellement sous Linux, précision étendue) a été converti en float
(comme le veut la norme C) ou non (bug 323 de gcc).



Tu veux dire que après
float scale=0.1;
on peut trouver des versions/optimisations de GCC qui vont remplacer
scale par 0.1 (au lieu de 0.1f) dans des expressions ultérieures ?

Si on arrive à cela, il y a effectivement un bogue majeur... car on ne
respecte plus les prescriptions de la machine virtuelle, et je ne pense
pas que cela reste dans le cadre des sauf-conduits pour les flottants
établis dans C99.


Quoique...
... je viens de m'apercevoir que l'opération utilisée était int(),
inconnu chez nous, donc ici ce sont les règles de C++ qui s'appliquent
concernant les conversions de flottants (et cela dépend entre autres des
différentes surcharges disponibles pour int() et pour operator/).

Donc, c'est complètement hors sujet dans ce groupe, en C on a déjà
suffisamment de mal avec <tgmath.h> pour devoir s'em***er avec un
langage 3× plus compliqué !


Antoine
Avatar
Vincent Lefevre
Dans l'article ,
Kojak écrit:

Le Thu, 26 Mar 2009 17:51:22 +0000 (UTC),
Vincent Lefevre a écrit :



> Dans l'article ,
> Kojak écrit:
>
> > Essaye avec l'option "-ffloat-store", ça peut aider...
>
> 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, 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
dit explicitement qu'il faut utiliser des variables:

-ffloat-store
Do not store floating point variables in registers, and inhibit
other options that might change whether a floating point value
is taken from a register or memory.

[...] Use -ffloat-store for such programs, after modifying them
to store all pertinent intermediate computations into variables.

Je ne sais pas si c'est la doc qui n'a pas été mise à jour ou si ça
dépend du contexte, ou autre...

--
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 ,
Jean-Marc Bourguet écrit:

Vincent Lefevre <vincent+ writes:



> Voilà, ce n'est pas tout, mais il faut que je termine de relire
> le livre qu'on est en train d'écrire dans notre équipe, qui va
> justement parler de tous ces problèmes et de plein d'autres choses
> sur l'arithmétique virgule flottante.



Tu l'annonceras ici STP (ou directement par mail -- mon adresse
est valide -- si tu crains qu'on t'accuse de spammer)?



Je compte l'annoncer ici, vu que des questions de virgule flottante
reviennent souvent ici.

--
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
Pierre Maurette
Antoine Leca, le 27/03/2009 a écrit :

[...]

Donc, c'est complètement hors sujet dans ce groupe, en C on a déjà
suffisamment de mal avec <tgmath.h> pour devoir s'em***er avec un
langage 3× plus compliqué !



Tiens, il y a quelques jours dans l'entête d'un wdfdio.cpp, je suis
tombé là-dessus:

// Why is this a .cpp file? This is a normal C language driver, with a
// .cpp file type. We do with with all our drivers here at OSR,
because we've
// found the strong type-checking you get with the C++ compiler to be
very
// helpful in finding errors.

Je le gardais sous le coude pour une période encore plus calme sur
fclc, mais l'occasion, l'herbe tendre...

--
Pierre Maurette
Avatar
Vincent Lefevre
Dans l'article <gqig5e$hkq$,
Antoine Leca écrit:

Le 27/03/2009 02:58Z, Vincent Lefevre écrivit :



> D'autre part, il n'est pas clair si le 0.1 (double précision, sauf
> éventuellement sous Linux, précision étendue) a été converti en float
> (comme le veut la norme C) ou non (bug 323 de gcc).



Tu veux dire que après
float scale=0.1;
on peut trouver des versions/optimisations de GCC qui vont remplacer
scale par 0.1 (au lieu de 0.1f) dans des expressions ultérieures ?



Oui, sauf que peut-être pas forcément dans ce cas, car 0.1 est une
constante, et le comportement sur tout ce qui peut être déterminé
à la compilation est parfois différent. Dans le cas général, c'est
le fameux bug 323 de gcc: après un cast ou une affectation, il ne
force pas la conversion du résultat dans le type sémantique (cela
se produit au moins avec l'arithmétique x87, la principale raison
étant qu'avec ce FPU, la précision d'arrondi est fixée dynamiquement).
Cela est testé par mon programme tst-ieee754.c sur

http://www.vinc17.org/research/fptest.fr.html

Je fournis aussi une archive contenant les résultats sur diverses
machines et un résumé.

Si on arrive à cela, il y a effectivement un bogue majeur... car on ne
respecte plus les prescriptions de la machine virtuelle, et je ne pense
pas que cela reste dans le cadre des sauf-conduits pour les flottants
établis dans C99.



Tu peux voir

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

même si certains y ont rapporté ici des non-bugs. C'est peut-être
une raison pour laquelle le bug avait été marqué comme invalide par
Andrew Pinski en juillet 2003, mais pas seulement. Il y a aussi eu
une discussion dans la liste de développement de GCC en juin 2005,
où il avait été dit que c'était le processeur x86 qui était buggé
et ne suivait pas la norme IEEE 754; je n'étais pas d'accord, mais
il a alors été dit que de toute façon le bug ne serait pas corrigé.
J'ai tout de même demandé sa réouverture en "suspended":

http://gcc.gnu.org/ml/gcc/2005-06/msg00678.html

Il a finalement été rouvert en "suspended", qui est son état actuel,
même s'il y a un patch (cf ci-dessous). Les commentaires les plus
intéressants du rapport de bug:

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

(où j'explique qu'il y a réellement un bug dans GCC), avec les
quelques commentaires qui suivent.

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

le patch de Joseph S. Myers, qui corrige le bug (je n'ai pas testé),
et les deux commentaires qui suivent.

Quoique...
... je viens de m'apercevoir que l'opération utilisée était int(),
inconnu chez nous, donc ici ce sont les règles de C++ qui s'appliquent
concernant les conversions de flottants (et cela dépend entre autres des
différentes surcharges disponibles pour int() et pour operator/).



Oui, peut-être, mais...

Donc, c'est complètement hors sujet dans ce groupe, en C on a déjà
suffisamment de mal avec <tgmath.h> pour devoir s'em***er avec un
langage 3× plus compliqué !



J'ai réécrit le code en C et j'observe le même problème, cf mes
tests dans le message <20090327025744$
du 27 Mar 2009 02:58:06 +0000. Ceci n'est pas très étonnant...

--
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, Pierre Maurette wrote:
Antoine Leca, le 27/03/2009 a écrit :

Donc, c'est complètement hors sujet dans ce groupe, en C on a déjà
suffisamment de mal avec <tgmath.h> pour devoir s'em***er avec un
langage 3× plus compliqué !



Tiens, il y a quelques jours dans l'entête d'un wdfdio.cpp, je suis
tombé là-dessus:

// Why is this a .cpp file? This is a normal C language driver, with a
// .cpp file type. We do with with all our drivers here at OSR,
because we've
// found the strong type-checking you get with the C++ compiler to be
very
// helpful in finding errors.

Je le gardais sous le coude pour une période encore plus calme sur
fclc, mais l'occasion, l'herbe tendre...



Et oui, l'incompétence...
Autant je comprends tout à fait l'approche ceinture et bretelle,
qui peut faire qu'on décide de compiler un code C avec un compilo C++
pour voir les messages d'erreurs, mais sans produire le code,
autant écrire du C et le compiler avec un compilo C++ montre
une incompétence importante.

Marc Boyer
--
Au XXIème siècle, notre projet de société s'est réduit
à un projet économique...
Avatar
Antoine Leca
Le 27/03/2009 15:53Z, Marc Boyer écrivit :
On 2009-03-27, Pierre Maurette wrote:
// Why is this a .cpp file? This is a normal C language driver, with a
// .cpp file type. We do with all our drivers here at OSR, because we've
// found the strong type-checking you get with the C++ compiler to be
// very helpful in finding errors.





Sans compter qu'étant donné d'une part les liens relativement étroits
qui existent entre OSR et Redmond (au moins les gens du noyau Windows),
et d'autre part le fait que les deux compilateurs C et C++ de Microsoft
sont assez proches entre eux (même si ce sont bien deux compilateurs
distincts comme GCC), cela montre que les gens de Redmond (au moins ceux
qui développent le compilo, peut être très^W un peu en froid avec les
sus-nommés) n'ont plus^W pas semble-t-il de volonté de produire un
compilo C avec des possibilités « très utiles de détection d'erreurs ».


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.


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).
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é].


Antoine
Avatar
espie
In article <gqj1ms$lhu$,
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.



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.



Ben le seul souci, c'est les ABI, les compilo C++ pratiquant du name-mangling
sur la plupart des plateformes pour pouvoir pratiquer la surcharge de
fonction.

Ca ne me parait pas non plus completement idiot, ni faire preuve
d'incompetence... "forcer" les gens a compiler avec le compilo C++ assure
que ce test sera fait (alors que si on demande juste aux gens de compiler
avec un compilo C++ pour regarder les warnings... on sait tres bien ce
que ca donne, et surtout que, Murphy aidant, ca ne sera pas fait le jour
ou ca serait utile).

Apres, les contraintes d'ABI sont assez simples a gerer (mais ca veut dire
rajouter du extern "C", et donc ne plus faire du C a proprement parler... et
je ne sais meme pas dans quelle mesure ca s'applique a un compilo windows,
on peut rever et imaginer que leur editeur de liens est un peu plus finaud
que celui d'Unix...), et les cas de problemes de compatibilite ascendante
se comptent sur une main. Evidemment, ca imposera de mettre des cast si
on veut utiliser malloc, et ca c'est un vrai probleme... mais je soupconne
que dans le contexte considere, il n'y aura pas de malloc...
1 2 3 4 5