Convertir de double à long Ronde sans Java
Je suis en train de convertir un double aléatoire pour un long temps sans arrondi ou en tronquant.
J'ai d'abord changer le double d'une chaîne de caractères, à savoir combien de décimales, il y a puis-je changer la valeur à long terme.
Mon problème est que le numéro de la dernière décimale n'est pas toujours exact, et je ne sais pas la raison et comment je peux le changer.
Voici le code:
double z=(double) myRandom(1, 20);
long test;
String s = Double.toString(z);
test=(long) (Math.pow(10, s.length()-s.indexOf(".")-1)*z);
System.out.println("z: "+z);
System.out.println("double converted to long: "+test);
Et c'est la sortie:
d: 19.625014811604743
double converti à long: 19625014811604744
d: 9.143326452202839
double converti à long: 9143326452202838
d: 5.8964228376511105
double converti à long: 58964228376511104
d: 15.045936360299917
double converti à long: 15045936360299918
d: 14.147950026532694
double converti à long: 14147950026532694
- J'ai oublié de vous poser une question
Double.toString(double)
n'est pas nécessairement de sortie ce que vous pourriez vous attendre à partir de seulement aveuglément l'impression de chaque chiffre de la mêmedouble
. Il fait un peu de magie pour essayer de se débarrasser de funky de répéter les chiffres des représentations binaires.- À virgule flottante, des erreurs d'arrondi. Pourquoi ne pas simplement prendre la chaîne que vous avez, remplacer
"."
avec""
, et ensuite d'analyser dans unlong
? Ou, vous pouvez aller de double -> BigDecimal -> (plusieurs BigDecimal par le facteur approprié de 10) -> BigInteger. Qui fonctionne également si vos changements de code pour permettre d'effectuer des doubles. - Honnêtement semble que l'OP est juste essayer de mettre en œuvre
BigDecimal
. - Pourquoi vous préoccupez-vous de l'exactitude de 16 chiffres d'un nombre aléatoire?
- à partir d'un "c'est juste" au travail en perspective, mais je recommande l'OP pour voir quelque chose de bizarre et je me demandais pourquoi il serait comme ça.
- Il serait comme ça parce que vous avez seulement 16 chiffres de précision et lorsque vous effectuez un calcul le dernier chiffre peut être légèrement trop haute ou trop basse. Cela est dû au fait que le double ne peut pas représenter toutes les valeurs de l'OP cite.
- Yup, j'ai posté une réponse avec qui il y a quelques minutes. J'étais juste de souligner que c'est bien de l'OP, pour ne pas simplement hausser les épaules et de dire "eh, assez bon", mais en fait se demander pourquoi il se produit.
Vous devez vous connecter pour publier un commentaire.
De l'édition de votre application actuelle:
Ou si vous voulez juste un hasard
Long
je vous conseille d'utiliserRandom.nextLong()
à la place.String s = z + "";
surString s = Double.toString(z)
?String
en Java, mais en utilisantDouble.toString
pourrait fonctionner tout aussi bien.""
le temp de chaîne que vous êtes en train de parler?Si votre objectif est d'obtenir de façon aléatoire un nombre de temps, alors je vous recommande fortement de l'aide de Random.nextLong() à la place.
Est gâcher votre double dans l'arithmétique, essayez quelque chose comme ceci:
Vous pouvez faire quelque chose comme ça...
Les autres réponses ont souligné la façon dont vous pouvez corriger ce problème, mais votre question a été pourquoi il arrive. La réponse est à virgule flottante d'erreur.
Les nombres à virgule flottante sont constitués de trois parties principales: un signe (+ ou -), une mantisse et un exposant. Essentiellement, le nombre est représenté comme étant essentiellement
(sign) (mantissa) * 2^(exponent)
(mais pas exactement -- voir les liens ci-dessous). Comme vous pouvez l'imaginer, pas tous les numéros adapte parfaitement dans cette représentation; certains doivent être approchée. L'exemple par excellence est le dixième, qui en binaire a une infinie répétition de la séquence et donc, doit être approchée en double.À des valeurs élevées -- plus de la mantisse peut represnt -- il y a quelques entiers qui ne peuvent pas être représentés exactement. Ce qui se passe à la 2^53; n'importe quel nombre supérieur à ce qui doit être approchée, et les chiffres que vous mentionnez sont de tels exemples.
Vous n'avez même pas besoin
Math.pow
pour le démontrer; littéraux fera l'amende juste.Ce sera d'impression:
Avis de la 4 à la fin de la deuxième valeur. 19625014811604744 est le nombre le plus proche de 19625014811604743 qui peut être représenté comme un double.
Liées à la lecture: