Ceci est IEEE 754 Question standard. Je ne comprends pas complètement la mécanique derrière elle.
public class Gray { public static void main(String[] args){ System.out.println( (float) (2000000000) == (float) (2000000000 + 50)); } }
4 Réponses :
parce qu'un float code>
ne peut contenir que 7 à 8 chiffres significatifs. C'est-à-dire qu'il n'a pas assez de bits pour représenter le nombre 2000000050 exactement, il est donc arrondi à 2000000000. P>
Spécifiquement parler, un Vous pouvez penser à un point flottant comme la voie de l'ordinateur faire la notation scientifique, mais en binaire. P>
La la précision em> est égale à Le nombre 2 000 000 050 a 9 chiffres significatifs. Le calcul ci-dessus nous dit qu'un signification 24 bits ne peut pas contenir de nombreux chiffres significatifs. La raison pour laquelle 2 000 000 000 œuvres car il n'y a que 1 chiffre significatif, il convient donc dans le signaland. P>
Pour résoudre le problème, vous utiliseriez un float code> est composé de trois parties: p>
journal (2 ^ Nombre de bits significatifs) code>. Cela signifie qu'un
float code> peut contenir
journal (2 ^ 24) = 7.225 code> chiffres significatifs. P>
double code> a > Comme il a un signaland 52 bits, qui est plus que suffisant pour représenter tous les numéros 32 bits possibles. P>
Je ne comprends pas cette déclaration: la raison pour laquelle 2 000 000 000 œuvres car il n'y a qu'un chiffre important, il convient donc à ce que cela concerne le signaland.
@Fabriziom: Comprenez-vous pourquoi le nombre de 2 000 000 000 ne comporte que 1 chiffre significatif, mais le nombre de 2 000 000 050 comporte 9 chiffres significatifs?
ok donc est écarté en 2 ^ 9 (2 = signification 2 bits) (9 = Exponent 4 bits)
@Fabriziom: Les mathématiques sont en réalité un peu plus compliquées, mais c'est essentiellement le gist.
dit clairement - 50 est une erreur d'arrondi lorsqu'un flotteur a une valeur de deux milliards. p>
Clairement, mais inexactement :-)
@Stephen - Pouvez-vous élaborer pourquoi?
Parce que 50 simplement le nombre 50. Étant donné que les erreurs d'arrondi réelles sont les différences entre 200000000.0 code> et
réel ((((float) 200000000) code> et entre
200000050.0 CODE> et < Code> réel ((flotteur) 200000050) code>.
Cela pourrait vous aider à comprendre la situation si vous envisagez un programme (C ++) comme ci-dessous. Il affiche les groupes d'entiers successifs qui sont arrondies à la même valeur de flottaison: sortie: p> ceci indique que le point flottant est Assez précis que pour représenter tous les entiers de 1999999850 à 1999999935, enregistrant à tort leur valeur de 1999999872. Donc, pour d'autres valeurs. C'est la conséquence tangible de l'espace de stockage limité mentionné ci-dessus. P> p>
La question n'est pas étiquetée c ++
@JeremyP: Je sais que, mais les formats de points flottants sont généralement normalisés sur une base matérielle et donc communs entre les langues, rendant les concepts applicables. J'arrive juste à aimer C ++ et je ne connais pas Java.
Oui, mais il n'est pas raisonnable de vous attendre à ce qu'un programmeur Java connaisse ce que les choses comme std :: Cout << Quelque chose code> réellement signifié.
@JeremyP: True, mais j'espère qu'ils pourraient transversir le programme avec la production et travailler suffisamment pour le réécrire en Java s'ils le souhaitent, ou du moins suivent le concept de base de la manière dont le double précision est utilisé pour passer à travers les valeurs que le flotteur ne peut pas représenter avec précision.
Vous trouverez peut-être cette astuce pour trouver la prochaine valeur représentable intéressante. Imprime P> The next float value after 2000000000 is 2000000128
The next double value after 2000000000.0000000 is 2000000000.0000002
Soigné. Semble dépendre de la signification (voir dans la réponse de Silico) étant dans les bits les moins importants de l'INT. Je ne sais pas comment cela tient sur différentes architectures, mais peut-être que Java gère toujours de toute façon?
Au fait, ce "problème" n'est pas limité à Java; Cela concerne la manière dont les flotteurs sont représentés en binaire, tels que définis par la norme IEEE 754.