Java : comment ça marche les double ? - Java - Programmation
Marsh Posté le 22-05-2006 à 10:18:27
En fait il considere que Double.MAX_VALUE == Double.MAX_VALUE - 1.0
Bizarre
Marsh Posté le 22-05-2006 à 10:34:31
Mais non, c'est normal, le double est, comme le float, un IEEE754, c'est lié à sa représentation interne :
http://people.uncw.edu/tompkinsj/133/numbers/Reals.htm
C'est une representation par mantisse/puissance. Le -1 étant faible par rapport au reste, il est mis de coté par l'arrondit naturel lié à la représentation.
Il y a what milles doc sur IEEE754 et tous ces détails.
Marsh Posté le 22-05-2006 à 10:44:58
Mais on s'en fout de ça nous (la representation interne), et non je trouve pas ça normal Car du coup on se retrouve bien avec un resultat abérrant dans l'absolu... (meme si je suis d'accord que 1.79 * 10^308, +ou- 1 c'est du chipottage mais bon !)
Et que vaut x la dedans (pour que ce soit vrai) ?
|
Marsh Posté le 22-05-2006 à 10:53:44
Double.Max_value ~ ∞
Par conséquant, tes cours de math te disent :
∞ = (∞ - x) quelle que soit la valeur de X
C'est donc un fonctionnement normal, à partir du moment où la précision de Double est insuffisante pour prendreen compte les valeur de x quand ce dernier est petit. A ce moment, Max_value est assimilée à ∞.
Marsh Posté le 22-05-2006 à 10:54:16
boulax a écrit : Mais on s'en fout de ça nous (la representation interne), et non je trouve pas ça normal |
Bah non, on s'en fout pas, vindougneugneu !
IEEE754 est la norme pour les flottants depuis 35 ans. Elle est cablée au niveau des processeurs, c'est donc elle qui est utilisée pour manipuler les flottants, quelque soit le langage. Dans le cas de calculs stricts, il faut passer à des nombres qui ont une representation complète, et c'est largmeent plus lent.
boulax a écrit :
|
il faut que x apparaisse dans la mantisse à la puissance courante, E=1023 pour le double.MAX_VALUE, et la mantisse est sur 52 bits. c'est donc un changement du 52eme bit de la mantisse.
Marsh Posté le 22-05-2006 à 10:56:30
Par contre, je ne pige pas bien un truc.
Je pensais que Double n'était pas un flotant. Je pensais que c'était comme le Double (alias de Numeric) de SQL92, c'est à dire un nombre justement avec une précision exacte... C'est balo que le même nom de type désigne deux concepts radicalement différents...
Surtout dans un langage d'abstraction matériel, où double fait clairement doublon avec float, puisque les registres du x86 ne peuvent pas être pris comme "modèle" pour dimentionner le float notamment.
Marsh Posté le 22-05-2006 à 10:59:26
Arjuna a écrit : |
C'est vrai en C++, pas en java. J'avais le doute, et j'ai été vérifié.
Arjuna a écrit : |
L'abstraction matérielle est celle de la JVM. Elle s'abstrait pas franchement du x86 de toutes façons, donc les types de base sont différents. Je serais pas surpris que les sparcs supportent le java double en natif et qu'il soit mappé sur plusieurs float dans le cas d'autres plateformes.
Marsh Posté le 22-05-2006 à 11:03:36
Arjuna a écrit : Double.Max_value ~ ∞ |
kadreg a écrit : Bah non, on s'en fout pas, vindougneugneu ! |
Bah le langage est pas censé nous abstraire de tout ce bordel ? (à moins qu'un double soit par définition autre chose qu'un grand nombre et que du coup on attende pas de lui le comportement normal d'un nombre)
kadreg a écrit : |
Marsh Posté le 22-05-2006 à 11:09:35
ça je suis d'accord.
mais justement : un seul type float ferait l'affaire.
de base, sur x86 ou autre, il utilise un registre float "natif".
si la taille de ces registres est insuffisante, il transforme en interne la réprésentation du nombre sur un mappage de ce nombre sur plusieurs registres, jusqu'à atteindre la précision maximale acceptée par la langage.
ça me semblait tout à fait naturel et logique comme fonctionnement.
je viens de vérifier, c'est pareil en C#... je veux bien que ça bouffe des perfs, mais pas plus que le GC par exemple... strange.
/me trouve que l'abstraction de la plateforme est un bon gros pipo en fait, puisque le même code est incapable de fonctionner de manière optimum d'une plateforme à l'autre du coup...
Marsh Posté le 22-05-2006 à 11:15:55
D'un point de vue purelement logique, si.
La preuve, ça se comporte pareil pour les nombres "petits".
Double / Float ont une précision extrêment faible lorsqu'ils approchent de leur valeur maximal, tout comme la valeur de ∞ est inconnue.
Pour cette raison, leur fonctionnement s'approche ce celui de cette variable mathématique pour les valeurs suffisament petites pour être en deça de la précision.
Evidement, si tu cherches à être puriste, contente toi des explications IEEE754, moi perso, je préfère mettre des mots simples et pas forcément exacts qu'une explication aussi complexe que farfelue... C'est plus facile à retenir.
Marsh Posté le 22-05-2006 à 11:21:55
D'ailleurs, en regardant la IEEE754, c'est pas stupide de dire Max_value ~ ∞ puisque c'est justement la dernière valeur représentable par ce type avant la représentation de ∞. A 1 bit près, on peux pas dire que ce soit vraiment loin, d'où le ~
Marsh Posté le 22-05-2006 à 09:25:11
Un programme java qui bouclait à l'infini m'a fait découvrir une abérration
double i = 1.0;
if (Double.MAX_VALUE <= Double.MAX_VALUE - i)
System.out.println("ohoh!" );
...et ce test est vrai !
Question : quelle doit être la valeur minimal de i pour que le test soit faux ?