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

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
Vincent Lefevre
Dans l'article <4bbb2b58$0$12974$,
Samuel DEVULDER écrit:

Non je parlais du WEB. C'est clair depuis le début. Je me cite à nouveau:

> Moi:
> > Vincent:
> > Tout dépend de l'implémentation, qui peut très bien utiliser
> > 1 à chaque fois (sauf pour zéro). Je rappelle que l'exposant est
> > binaire.
>
> Binaire? genre p-10 veut dire 2-16? la doc que j'ai trouvée
> http://www.opengroup.org/onlinepubs/000095399/functions/printf.html
> dit exposant décimal (donc 2-10 = 1/1024 ici).



POSIX contient de nombreuses erreurs (il n'y a qu'à voir ce qui passe
sur la liste de l'Austin Group). Un autre exemple: la confusion entre
NULL et pointeur nul.

Son conseil aurait été plus utile s'il avait filé l'url ou, mieux,
recopié le passage de la norme qui s'y réfère. Je l'ai fait, il dit que
ca parle de "binary exponent", je ne l'ai pas retrouvé. :-/



7.20.1.3
[...]
a 0x or 0X, then a nonempty sequence of hexadecimal digits
optionally containing a decimal-point character, then an optional
binary exponent part as defined in 6.4.4.2;
^^^^^^^^^^^^^^^

--
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
Vincent Lefevre
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).

[Norme C, printf]
The exponent always contains at least one digit, and only as manymore
digits as necessary to represent the decimal exponent of 2.



C'est horriblement mal dit, et AMHA, devrait être vu comme un défaut
(d'ailleurs, "binary exponent" est majoritaire).

Ce n'est pas le seul endroit où la norme est mal écrite, et
celle-ci doit aussi être lue avec un sens critique. Cf l'enfilade
"Conditional as lvalue" dans comp.std.c.

--
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
Antoine Leca a écrit :
../.. et là où le problème devient brûlant,
c'est que sur les plateformes les plus répandues à l'heure actuelle, on
ne se rend pas compte du problème, car il se trouve que unsigned et long
ont la même représentation mémoire.



Oui. D'un coté on peut se demander si un problème qui ne se manifeste
pas est un vrai pb ou un faux pb. De l'autre on peut vouloir devancer le
pb et le corriger par anticipation. L'usage montre quand même qu'il y a
toujours un risque non nul à vouloir faire mieux et réparer un truc qui
marche. Le tout est de savoir si le bénéfice de l'anticipation dépasse
le risque de casser un truc qui marchait.


Sur une machine 16 bits, printf("%x", un_long) marche effectivement
(sauf cas /très/ particuliers), mais n'affiche pas le même résultat que
sur une machine « habituelle », et ÀMHA le résultat « faux » est celui
de la machine 16 bits.


Perso je n'aime pas les phrases sèches: "ce code est faux".



Je crois qu'on avait compris. Cependant, il ne m'a pas semblé avoir
écrit cela, et sûrement pas dans le mien message auquel tu réponds.



Oui tout à fait, c'était pas pour toi.

Il lui manque quelque chose indiquant sous quelle hypothèse c'est
faux.



Mmm. D'abord, je pense faire en général un effort pour indiquer, au
moins sommairement, pourquoi je considère qu'un code ne va donner le
résultat escompté. Il est vrai que c'est parfois trop bref, cf. supra.

Ensuite, un des principes de la norme C, c'est de définir « bon », qui
s'y épelle « strictement conforme », et qui est en gros défini comme
« produit le même effet partout » ; après, on peut ergoter sur faux par



Oui, le même effet partout sauf où la norme ne le précise pas (1er digit
du %a, le UB, etc). Et encore j'ai cru voir que sur certains aspects, la
norme est imprécise et peut avoir deux interprétations distinctes.
Disons que la norme diminue le risque d'avoir un code qui ne produise
pas le même effet partout. C'est une probabilité, pas une certitude.

rapport à strictement conforme, toussa (surtout que pour compliquer, on
a la notion de « programme conforme » qui signifie « accepté par un
compilateur C conforme », ce qui inclut donc tous les programmes Fortran
et assembleur compilables par GCC...)


Un code peut être faux sous C99 et légitime sous C89.



C'est vrai mais c'est plutôt rare ; et c'est le plus souvent à cause de
l'utilisation de fonctionnalités comme le int implicite, qu'il vaut
mieux corriger le plus vite possible. Un autre problème peut venir des
noms de fonctions standards introduits par C99, et là aussi dans la
pratique, le programmeur va être obligé de suivre le train (c'est pareil
pour les mots clés de C++ ou les fonctions de Posix).

Après, je sais très bien qu'il y a des programmes écrits pour C89,
considérés comme bien écrits, qui posent problème lorsqu'on les passe
sur un compilateur C99 : le plus évident sont les (quelques) programmes
qui s'appuient sur la certitude que long est le plus grand type entier ;



C'était vrai et le reste pour beaucoup de monde. Je sais pas pourquoi,
mais j'ai toujours connu sizeof(long)=4 depuis très très longtemps (et
même à une époque où sizeof(int)==2). Bon j'ai laissé tombé unix il y a
quelques années, mais même à l'époque sur le HP et les sparcs il me
semble que sizeof(long) était aussi lui à 4 (machines 64bits pourtant).
Pour avoir un entier 64bits on utilisait long long quand le compilo le
supportait, sinon un utilisait un tableau de 2 long comme mon exemple.

cependant, je crois qu'ils servent beaucoup plus souvent d'alibi pour
cacher une multitude de programmes mal écrits, par exemple qui supposent
que long est un entier sur 32 bits.



Il faudra attendre que les 64bits se généralisent et que les gens
continue à coder en C sur ces machines. On y vient..

Antoine



sam.
Avatar
Samuel DEVULDER
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!

[Norme C, printf]
The exponent always contains at least one digit, and only as manymore
digits as necessary to represent the decimal exponent of 2.



C'est horriblement mal dit, et AMHA, devrait être vu comme un défaut
(d'ailleurs, "binary exponent" est majoritaire).



Si tu le dis (je ne veux pas juger du style d'écriture de la norme)..
mais c'est un argument peu commun, limite mauvaise foi. Je tacherais de
l'utiliser la prochaine fois moi aussi, ca semble pratique. Mais il
soulève le problème de savoir si on peut accorder le moindre crédit dans
une norme qui est finalement aussi mal écrite.

Ce n'est pas le seul endroit où la norme est mal écrite, et



Oui.. Elle est décidément très pourrie cette norme. Ca craque de
partout... Viiite la C1x!!

bon je déconne (j'espère que ca se voit). Il n'empêche que l'exposant 2
s'écrit en décimal après le 'p', et cela même si la norme est mal
écrite. On en demandait pas plus au départ.

sam (ca va finir par un concours de bit le plus long cette histoire si
ça continue)
Avatar
Samuel DEVULDER
Antoine Leca a écrit :
Samuel DEVULDER écrivit :
Antoine Leca a écrit :
Je ne sais pas si dans ta pensée, le mot littérature ci-dessus avait ce
sens ;


Non je parlais du WEB. C'est clair depuis le début.



Je suis probablement un autre crétin, et certainement d'un autre siècle,



Pourquoi crétin? Quel est l'autre? Il n'y a pas de raisons. Ne te sens
pas offensé.

mais il ne m'est jamais venu à l'idée de lire « web » derrière
« littérature » ; même scientifique.



Ben pourquoi? Sur papier ou électronique ça reste un truc écrit, pas une
émission de radio ou de TV. Bref, c'est de la littérature, enfin il me
semble.

Je dis tout cela pour que comprennes un peu nos réactions, il n'y a pas
d'acrimonie, il y a juste parfois des différences d'interprétation.

Cela étant, la norme Posix que tu cites (site opengroup.org) est
effectivement un exemple de littérature au sens où je l'ai décris
(et je suppose que tu lus l'introduction de cette page, marqué CX).


Oui peut être, mais en quoi le background change ce qu'on dit?



? Si quelqu'un te dit « Viens ici ! », est-ce que ta manière de réagir
change selon que
- il s'agit de ta mère (et tu as 5 ans) ;



Et même si tu as dépassé les 65ans c'est pas mieux non plus! :-p

- il s'agit d'un policier en tenue ;



Mauvais point pour lui s'il tutoie un citoyen. On a connu des préfets
mutés pour moins que cela.

- il s'agit d'une femme également « en tenue », vers Pigalle ;
- il s'agit d'un homme visiblement éméché.



Heu oui.. mais tous ces cas sont discriminants, le titre ou la fonction
est écrit sur leur figure (ou ailleurs, je veux pas savoir!). Expert es
IEEE ca se trouve où au juste dans une adresse email?

Je n'ai pas dit que Vincent rentre dans une quelconque de ces cases !



;-) ne nous le vexe pas. ;-) Je sais pas s'il faut prendre toute cette
partie de la discussion au sérieux.


Est-ce qu'un type ultra compétant est plus utile qu'un crétin quand
tous les deux disent "Ce code est faux, cf C99"?



Je me referai au conseil à propos des ouvrages de référence sur les
flottants.



Ah ok. non pas moi.. je reste sur les 1er posts de Vincent dans le sujet
qui étaient assez... spartiates.

Là tu as changé le contexte (et je suppose que tu voulais
écrire « compétent »).



Oui.


Par ailleurs, il y a un « style Usenet » (que l'on rencontre aussi dans
les courriers électroniques), qui cultive un laconisme esthétique. Ce



C'est beau de dire "beurk / ce code est faux"? Ah oui, ok d'accord.
C'était pas un message pour aider quiconque, c'était pour être
esthétique. Je comprends mieux mon désarroi. La prochaine foi j'y serais
préparé, je j'ignorerais promis. ;-)

style se perd ; les littéraires traditionalistes s'en réjouiront,
d'autres y voient la mort de Usenet ; mais il paraît difficile
aujourd'hui de le fustiger, surtout sur Usenet, il faut donc faire avec.


Son conseil aurait été plus utile s'il avait filé l'url ou, mieux,
recopié le passage de la norme qui s'y réfère. Je l'ai fait, il dit que
ca parle de "binary exponent", je ne l'ai pas retrouvé. :-/



6.4.4.2 (et par conséquent 7.20.1.3)

Le fait que l'on trouve "decimal exponent of 2" dans 7.19.6.1 (et 7.24)
ne me semble pas cohérent. Mais c'est un avis purement personnel.
De toute manière, toute formulation aura une part d'ambiguïté.



Dans le fond on se fiche de savoir si c'est mal écrit ou pas. Ce qui
compte est de savoir ce qui suit le "p" dans le %a s'interprète comme du
décimal ou pas (est-ce que p100 veut dire "deux puissance cent" ou "deux
puissance huit" ou "deux puissance deux-cent-cinquante-six"). C'est pas
plus compliqué que cela.

Les documents auxquels tu fais référence insistent (et je le comprend
tout-à-fait, car ce n'est pas évident, surtout du fait du contexte) sur
la forme --en base 10, donc-- de la valeur de l'exposant ;


C'est ce qu'on veut savoir quand on fait un printf (le fait que ce soit
binaire en mémoire on s'en tamponne pour une sortie).



Pas exactement. C'est en fait tellement gros que tu le considère comme
évident, mais tu as _aussi_ besoin de savoir quelle est la base de la
numération (B=2 pour %a) pour comprendre comment interpréter le nombre
m×B^e ; en effet 16 aurait aussi bien pu être utilisé, car après tout
les chiffres de la mantisse sont en base 16, eux.



Oui, mais dès le début j'ai indiqué que le p signifiait "deux
puissance". Donc impossible à avoir "16puissance" à la place.

Le problème entre Vincent et moi sur ce truc c'est que quand on parle
des nombres qui suivent le "p", il dit binaire par rapport au fait que
p=2^d ce que je juge inutilement précis/imprécis car
- p est en lui même "puissance de deux"
- ca ne dit pas comment interpréter les nombres suivant: en base dix,
deux ou seize? (16 serait logique par référence à la fraction à ce
moment là)

Bon de toute façon ça ne sert a rien, on a fait le tour du sujet. Ceux
qui veulent des détails se réfèreront aux paragraphes 6.4.4.2 de la
norme, ou 7.19.6.1 ou étais-ce 7... oulala ca m'embrouille toute cette
norme mal écrite, bref se réfèreront à l'extrait intégral posté ce matin
même. ;-p

Par contre, c'est vrai que le fait que ce soit stocké en mémoire en base
2, 16 ou 10 n'a aucune espèce d'importance.



Tout à fait: Dix s'écrit à l'écran de la même façon sur une machine
binaire, octale ou BCD.

sam.
Avatar
Samuel DEVULDER
Vincent Lefevre a écrit :

POSIX contient de nombreuses erreurs (il n'y a qu'à voir ce qui passe
sur la liste de l'Austin Group). Un autre exemple: la confusion entre
NULL et pointeur nul.



Ah ok. Donc il faut se fier à des docs inexactes, mais quand on publie
un code jouet inexact par rapport à la doc on passe au lance flamme.. Ok
d'accord. Super!

Son conseil aurait été plus utile s'il avait filé l'url ou, mieux,
recopié le passage de la norme qui s'y réfère. Je l'ai fait, il dit que
ca parle de "binary exponent", je ne l'ai pas retrouvé. :-/



7.20.1.3



7.20.1.3 The strtod, strtof,and strtold functions

Oui on voit bien le rapport avec printf!! Ca saute au yeux!!

[...]
a 0x or 0X, then a nonempty sequence of hexadecimal digits
optionally containing a decimal-point character, then an optional
binary exponent part as defined in 6.4.4.2;
^^^^^^^^^^^^^^^




C'est pas printf du tout tout ca. Il faut arrêter avec la mauvaise foi
les gars. Au mieux 6.4.4.2 se réfère aux constantes dans le code, mais
en aucun cas au format de sortie du printf. Ca suffit de déconner avec
le standard, c'est pas fait pour jouer, vous allez finir par nous
l'abimer. :-)

sam.
Avatar
Samuel DEVULDER
Vincent Lefevre a écrit :
Dans l'article <4bbb4fc0$0$23437$,
Samuel DEVULDER écrit:

Encore faut il que ce soit une vraie erreur. Un bout de code
juste pour C89 pourra être considéré comme une erreur en C99.


C'est très rare.





Peut-être, mais depuis être très rare quand devient une raison valable?



J'aurais pu ajouter que les codes qui ne compilent plus en C99
sont dans leur très grande majorité des codes sales (je ne connais
même pas de code "propre" qui provoque une erreur en C99).



Ca veut dire quoi "sale" pour toi? Non conforme à C99? Ah oui tout
s'explique, c'est clair comme une tautologie!! Ce que tu peux juger sale
avec tes yeux de C99 était légitime sous K&R ou ANSI.. Il ne faut pas
juger le passé avec des lunettes modernes.

Est-ce sale d'écrire "static a = 4" dans du code? Pas forcément. En C89
int est implicite et le code se comprend par tous.

Dialogue:

Perso1 => Oui mais l'implicite c'est pas-bien(tm)!
Perso2 => Ah ok, mais quand on écrit static long a = 4 en C99 c'est bien
alors?
Perso1 => Oui!
Perso2 => Mais le long n'est pas un type. Le vrai type c'est "long int".
"int" est encore implicite en C99.
Perso1 => Ah oui l'implicite c'est propre alors!

==> La morale de l'histoire: sale/propre sont des jugements de valeur
qui n'ont pas la place dans un domaine... technique.

Voici quelques exemples (non exhaustifs) de ce qui passait sous C89 mais
plus sous C99:

http://usenix.org/publications/login/2002-10/pdfs/mccluskey.pdf



Du code C89 sale... D'ailleurs, certains exemples sont mauvais même
en C99, e.g. oubli du "return 0;".



même en C99? Oui surtout en C99! parce qu'en C89 ca passe, cf:
f() {... blabla; if(truc) return; blabla...}

$ gcc t.c -fsyntax-only -pedantic -ansi -stdÈ9
==> pas d'erreur

$ gcc t.c -fsyntax-only -pedantic -ansi -stdÉ9
==>t.c:1: warning: return type defaults to `int'
==>t.c: In function `f':
==>t.c:1: warning: `return' with no value, in function returning non-void

Grossièrement pour ceux qui ne savent plus lire du vieux C: f est une
fonction qui retourne rien, d'où return vide. Logique. Sauf que rien
signifie implicitement int en C89. En pratique ca veut dire que le
compilo ne retourne rien de spécial à la fonction. Il va peut être
utiliser cela pour optimiser. Qui sait?

Si on râle à propos du code incorrect, et même sale, c'est pour
une bonne raison...



Parce qu'on est des râleurs professionnels? non, quand même pas, hein..
rassure nous. ;-)


Autre truc. C99 est plus stricte que C89. Normalement C89 laisse passer
ce qui suit, mais pas C99:
char *s=...
unsigned char *t=s; /* erreur avec C99 */



Ça me semble valide en C99. Pourquoi ne le serait-ce pas?




==> pointer targets in initialization differ in signedness.


Quand on ne précise pas le contexte, c'est celui de la norme C ISO.
La seule norme C est actuellement la version de 1999 (a.k.a. C99).
C89 n'est plus une norme, même si on peut en parler...





Pourquoi ?



Parce que C89 n'est plus une norme.



Pourquoi ca n'est pas une norme? Parce que ca n'est plus une norme, pardi!

Décidément la tautologie du début n'est pas loin. Tu voulais peut être
dire que ce n'est pas une norme parce que c'est un *standard*. Ah oui ca
change tout en effet. (ANSI X3.159-1989)

sam (0+0=tête à toto, logique!)
Avatar
Antoine Leca
Samuel DEVULDER écrivit :
Les machines ayant un CHAR_BIT de 12 sont rares elles aussi, et pourtant
j'en connais qui grognent quand ils voient écrit:
char buf[sizeof(double)];



En dehors du fait que je préférais unsigned char, je ne vois pas le
problème avec le truc ci-dessus, même avec des char sur 12 bits et des
doubles allongés à 72 bits, sizeof(double) vaudra 6, c'est tout.

parce que ça introduit des pad-bits pas super clairement.



Mouais. Des bits de remplissage, il y en plus souvent que cela. Sans
aller chercher loin, sur un bête PC d'aujourd'hui, avec les sympathiques
«précision étendue» du x87 sur 80 bits nominaux, on trouve des
représentations mémoire (type long double) sur 96 bits (qui préserve
l'alignement 32 bits) et d'autres sur 128 bits (préserve l'alignement
« naturel » du processeur sur 64 bits, mais gâche beaucoup d'espace).


Voici quelques exemples (non exhaustifs) de ce qui passait sous C89 mais
plus sous C99:

http://usenix.org/publications/login/2002-10/pdfs/mccluskey.pdf



Très succinct, et pas vraiment dissuasif à mon avis : en gros, il dit
bien qu'il y a des choses à changer, mais qu'il y a aussi des nouveautés
qui peuvent être intéressantes : c'est comme n'importe quelle réforme.
J'ai vu des revues bien plus méchantes.
De plus, son avis sur le « problème » de la compatibilité C++ montre
qu'il a assez mal anticipé les tempos relatifs, en particulier en
surévaluant la vitesse de migration vers C99...


Autre truc. C99 est plus stricte que C89. Normalement C89 laisse passer
ce qui suit, mais pas C99:
char *s=...
unsigned char *t=s; /* erreur avec C99 */



Uh ? Là, c'est juste que la conformité des compilateurs (et de leurs
messages) s'est accrue entre temps. Le fond de la norme n'a pas à ma
connaissance bougée sur ce point.


Autre trucs venant directement de K&R et devenus invalide au fil du
temps (et encore, je crois qu'on en discute encore de la validité de
telle constructions dans les milieux zotorizécomondi):
http://www.c-faq.com/struct/structhack.html



Et ? La construction était officiellement invalide en C90 (et marchait
dans la pratique), c'est pareil en C99 sauf qu'en plus, le comité a
rajouté un moyen officiel (quoique un peu différent) d'obtenir le même
effet ; en plus c'était souvent facile à implémenter puisque comme dit
précédemment, cela marche tout seul dans la pratique, donc faut pas se
priver.


Antoine
Avatar
Antoine Leca
[ Sur une machine 16 bits, printf("%x", un_long) ]

Samuel DEVULDER écrivit :
Antoine Leca a écrit :
../.. et là où le problème devient brûlant,
c'est que sur les plateformes les plus répandues à l'heure actuelle, on
ne se rend pas compte du problème, car il se trouve que unsigned et long
ont la même représentation mémoire.



Oui. D'un coté on peut se demander si un problème qui ne se manifeste
pas est un vrai pb ou un faux pb.



Sur une machine 16 bits, moi j'appelle cela un vrai problème (non
conformité aux spécifications) ; évidemment, ce n'est pas suffisant en
soi pour obtenir la correction, il faut aussi convaincre le programmeur
qu'il s'agisse d'un problème («c'est comme ça», «ça marche chez moi»).

Le tout est de savoir si le bénéfice de l'anticipation dépasse
le risque de casser un truc qui marchait.



Toutàfê. Mon avis personnel à moi-même, c'est que l'insertion d'un petit
l devant le x amène un gros bénéfice pour un risque très amuï. YMMV.

Et encore j'ai cru voir que sur certains aspects, la
norme est imprécise et peut avoir deux interprétations distinctes.



Oui : un document de 600 pages n'est pas forcément correct du premier
jet. Cependant, par rapport à la situation de 1989, on en est maintenant
arriver à un niveau de pinaillage qui a lassé la plupart des acteurs...


Disons que la norme diminue le risque d'avoir un code qui ne produise
pas le même effet partout. C'est une probabilité, pas une certitude.



Argument imparable, surtout avec moi ; et j'ai cessé de cherché la
certitude en ingénierie informatique il y a très longtemps, bien avant
d'entendre parler de Gödel.


Après, je sais très bien qu'il y a des programmes écrits pour C89,
considérés comme bien écrits, qui posent problème lorsqu'on les passe
sur un compilateur C99 : le plus évident sont les (quelques) programmes
qui s'appuient sur la certitude que long est le plus grand type entier ;



C'était vrai et le reste pour beaucoup de monde.



Mouais. Gros doute. En fait, ce ne fut vraiment vrai que pendant un
certain âge d'or (genre 1975-1990, qui induit une certaine nostalgie).
Dès l'arrivée des crayettes vers 1988, il fallut faire un choix entre
- long est le type le plus long
- long est un type qui garanti 32 bits, y compris sur un PDP11/PC
et c'est la seconde version qui a primé, parce que c'est ce que disait
K&R, et ensuite parce qu'à l'époque il y avait encore pas mal de PDP11
et (surtout) de PC-8086, et pour pas mal d'années, donc les nouveaux
venus ont été obligés de tordre le dogme ; d'où long long, qui apparaît
à beaucoup (dont moi) comme un horrible bricolage mais a l'avantage de
ne pas introduire de nouveau mot clé, et l'avantage BEAUCOUP plus
important de ne pas casser la montagne de code qui faisait aveuglément
l'hypothèse long2 bits...


Je sais pas pourquoi, mais j'ai toujours connu sizeof(long)=4 depuis
très très longtemps (et même à une époque où sizeof(int)==2).



Voui. Et tu n'es pas le seul, des monceaux d'informaticiens ont les
mêmes idées préconçues. Cela va même au point que chez Microsoft (qui se
préoccupe beaucoup de ses utilisateurs), ils n'ont pas pu casser cela
pour les machines 64 bits, et leur seule solution, cela a été de forcer
la migration vers d'autres langages et perdre beaucoup en portabilité
autres d'autres bases de code (dont Unix). Migration qui sera d'ailleurs
la seule solution à terme des dits informaticiens, car on voit bien que
les inconvénients de C pèsent de plus en plus dans la balance, et les
remèdes (genre programmation sûre) sont honnis.


Bon j'ai laissé tombé unix il y a
quelques années, mais même à l'époque sur le HP et les sparcs il me
semble que sizeof(long) était aussi lui à 4 (machines 64bits pourtant).



Il y a eu une période (plus longue chez Sun qu'ailleurs) où les deux
modèles (ILP32 et LP64) cohabitaient (mal), justement à cause de la
base. Depuis un peu plus de 10 ans (LFS ?), il n'y a plus de débat dans
le monde Unix, c'est LP64 autrement dit longd bits.
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).


Antoine
Avatar
Jean-Marc Bourguet
Antoine Leca writes:

Il y a eu une période (plus longue chez Sun qu'ailleurs) où les deux
modèles (ILP32 et LP64) cohabitaient (mal), justement à cause de la
base. Depuis un peu plus de 10 ans (LFS ?), il n'y a plus de débat dans
le monde Unix, c'est LP64 autrement dit longd bits.



http://www.unix.org/version2/whatsnew/login_64bit.html

In 1995, a number of major UNIX vendors agreed to standardize on the
LP64 data model for a number of reasons:

A+

--
Jean-Marc
FAQ de fclc: http://www.levenez.com/lang/c/faq
Site de usenet-fr: http://www.usenet-fr.news.eu.org