NumberFormatException: Infini ou NaN
J'ai une méthode qui prend n et renvoie la n-ième nombre de Fibonacci. À l'intérieur de la méthode de la mise en œuvre-je utiliser BigDecimal
pour obtenir le n-ième nombre de Fibonacci puis-je utiliser la méthode toBigInteger()
pour obtenir le numéro de la BigInteger
objet et c'est sûrement parce que je suis de travailler avec de grands nombres dans mon application.
Je continue à obtenir de bons résultats jusqu'à ce que je passe 1475 comme un argument en faveur de ma méthode. Je reçois NumberFormatException: Infinite or NaN
dans ce cas, sans raison claire pour moi.
Pourriez-vous svp m'expliquer pourquoi ai-je cette exception?
Voici ma méthode:
BigInteger getFib(int n){
double phi = (1 + Math.sqrt(5))/2;
double squareRoot = (Math.sqrt(5)) + (1/2);
BigDecimal bd = new BigDecimal(Math.floor(Math.pow(phi, n)/(squareRoot)));
return bd.toBigInteger();
}
OriginalL'auteur Kareem | 2013-08-03
Vous devez vous connecter pour publier un commentaire.
Votre
Math.pow(phi, n)
est trop gros(Infini),double est incapable de stocker,utiliser BigDecimal à la place.Comment au sujet de l'écoulement:
à partir de la formule:
Mise à JOUR:
de la façon décrite ci-dessus est inexacte parce que les Mathématiques.sqrt(5) n'a pas assez de précision que le commentaire dit. J'ai essayé de culculate sqrt(5) avec plus de précision à l'aide de Netown de la méthode,et a trouvé que
x1.pow(n).subtract(x2.pow(n)).divide(...)
est très chronophage,il spended environ 30 secondes pour n = 200 dans mon ordinateur.Je pense que la façon récursive avec un cache est encore plus rapide:
Il passer 7 ms dans mon ordinateur pour n = 2000.
Je ne suis pas sûr de ce produit correct nombres de fibonacci au-dessus de 71, à cause de la précision limitée de
Math.sqrt(5)
. Selon OEIS oeis.org/A000045/b000045.txt la 1475th nombre de fibonacci est 80776376321562253452154706580907152472160058839390611448949567098441231253468434896849142844747379890769208411232896054029055178267612427002841980625179761093160192801001760246411376424603323375022055947591818021711030476170155984070706514302882384774850491778697586460466725335267737494971685815687040886025.Oui ... d'obtenir une valeur précise de cette formule va être extrêmement difficile. 1) BigDecimal numéros fixes de la précision à la droite de la virgule décimale. 2) Vous ne pouvez pas utiliser
Math.sqrt(5)
... il n'est pas assez précise.Impressionnant. j'ai essayé de boucles, mais c'est trop curmbersome puis j'ai donné la récursivité à court et à mesure que le nombre a augmenté, il a ralenti maintenant, revenons à ce et tout est bon. la mise en cache pour améliorer la vitesse
OriginalL'auteur BlackJoker
Votre problème est ici:
le résultat de
Math.floor(Math.pow(phi, n)/(squareRoot))
est de vous donner soit infini ou NaN.Selon la BigDecimal javadoc que le constructeur (
BigDecimal(double)
) pourrait jeter uneNumberFormatException
si vous utilisez un double de la valeur infinie ou NaNOriginalL'auteur morgano
Ce n'est pas la cause de l'INF /NaN mais c'est absolument faux. Cette ...
... est équivalent à ceci ...
... parce que
(1/2)
est une division d'entier, en retournant une valeur de type entier; c'est à dire zéro.En fait, je pense que l'explication la plus probable pour les INF /NaN, c'est que "phi1475" est trop grand pour être représenté comme un
double
. Ainsi, lepow
méthode est de retourINF
... ce qui est la façon dont il est "trop grand" est représenté comme un nombre flottant en Java.Si vous voulez calculer les nombres de Fibonacci de cette façon, vous devez utiliser une représentation qui est capable de représenter un très grand nombre de personnes concernées ... et de les représenter avec une précision suffisante. La Java
double
type ne peut pas faire cela. Et en effet, il est difficile de faire le calcul à l'aide deBigDecimal
... que les commentaires sur le a accepté de répondre à démontrer!Je vous recommande d'utiliser la relation de récurrence. Il va être beaucoup plus simple ... et probablement plus efficace ainsi.
Essayez
round
avec un mode d'arrondi deFLOOR
. Mais je pense que l'aide de la relation de récurrence est susceptible d'être beaucoup plus rapide et plus fiable.OriginalL'auteur Stephen C
Ce n'est pas une bonne idée de créer
BigDecimal
avec des float ou double, car son nouveau limite la portée de leurvous devez créer un BigDecimal à la première et à faire des opérations à ses fonctions telles que:
int
) les valeurs.OriginalL'auteur Hossein Nasr