Pourquoi Java implicitement (sans cast) convertir un `long` pour un `float`?
À chaque fois que je crois que je comprends sur le casting et les conversions, j'ai trouver un autre comportement étrange.
long l = 123456789L;
float f = l;
System.out.println(f); //outputs 1.23456792E8
Étant donné qu'un long
a une plus grande profondeur de bits qu'un float
, je m'attends à ce qu'un cast explicite serait nécessaire pour que cette compilation. Et il n'est pas surprenant, nous voyons que nous avons perdu de la précision dans le résultat.
Pourquoi est une fonte pas nécessaire ici?
Vous devez vous connecter pour publier un commentaire.
La même question pourrait être posée de
long
àdouble
- les deux conversions risquez de perdre des données.L'article 5.1.2 de la Spécification du Langage Java dit:
En d'autres termes, même si vous risquez de perdre des données, vous savez que la valeur sera toujours dans l'ensemble de la gamme du type de cible.
Le choix pourrait certainement avoir été faite à exiger que toutes les conversions implicites de ne pas perdre de l'information à tous -
int
etlong
àfloat
aurait été explicite etlong
àdouble
aurait été explicite. (int
àdouble
est correct; undouble
a suffisamment de précision pour représenter avec précision tous lesint
valeurs).Dans certains cas, cela aurait été utile - dans certains cas, même pas. Le langage de conception est une question de compromis; vous ne pouvez pas gagner 'em all. Je ne suis pas sûr de ce que la décision que j'aurais fait...
La Java Langage de Spécification, Chapitre 5: la Conversion et à la Promotion de la traite de cette question:
Pour le dire autrement, la JLS fait la distinction entre une perte de ampleur et une perte de précision.
int
àbyte
par exemple est un (potentiel) de la perte de l'ampleur parce que vous ne pouvez pas stocker 500 dans unbyte
.long
àfloat
est un risque de perte de précision, mais pas de l'ampleur en raison de la fourchette de valeur pour les flotteurs est plus grande que celle de la nostalgie.La règle est donc:
Subtile? Assurez-vous. Mais j'espère que les efface, jusqu'.
double
àlong
être explicite, comme c'est le cas actuellement? L'intuitif (OMI) le raisonnement est "être explicite si vous risquez de perdre de l'information" - mais cela ne veut pas tout tenir ici.1E39
sera correctement être considéré comme impossible à distinguer de quelque chose de plus grand (la préservation de l'ampleur), mais un moulagedouble
donnera une valeur qui à tort de comparer plus de 1E308. C'est un des centaines d'ordres de grandeur d'erreur.Si vous êtes correct de dire qu'une longue utilise plus de bits en interne qu'un flotteur, le langage java fonctionne sur un élargissement de la voie:
octet -> court> int -> long -> float -> double
Pour convertir de gauche à droite (un élargissement de conversion), il n'y a aucune conversion n'est nécessaire (ce qui est pourquoi long à flotteur est autorisé). Pour convertir la droite vers la gauche (un rétrécissement de conversion) un cast explicite est nécessaire.
Quelque part, j'ai entendu cela. Le flotteur peut stocker dans la forme exponentielle comme nous l'écrire. '23500000000' est stockée en tant que '2.35e10' .Donc, le flotteur a de l'espace à occuper la gamme des valeurs de long. Le stockage dans la forme exponentielle est aussi la raison pour la perte de précision due.
float
, 4 octets, peut contenir l'ampleur de 8 octetslong
, tandis que pour autant sacrifier la précision. Cette réponse n'est pas de répondre complètement à cette question, mais il ne s'ajouter à la discussion. Il pourrait être mieux adapté qu'un commentaire. On a besoin de la référence et de comprendre le IEEE standard for floating points je pense que pour vraiment comprendre comment cela est possible.