2015-08-16 5 views
2

Je développe une application de la chimie, et je dois inclure le numéro d'Avogadro: (602200000000000000000000)trop grand nombre pour BigInteger

Je ne sais pas vraiment si je peux utiliser la notation scientifique pour le représenter comme 6.022 x 10x23 (Impossible de mettre l'exposant). J'ai d'abord utilisé double, puis long et maintenant, j'ai utilisé java.math.BigInteger.

Mais il dit toujours qu'il est trop grand, que puis-je faire ou devrait-il être juste pour beaucoup pour un système?

+5

Si BigInteger dit trop grand, vous devez installer plus de RAM. – csmckelvey

+3

Le problème n'est probablement pas BigInteger. Un entier de cette taille peut être représenté dans environ 80 bits. Même en tenant compte des autres frais généraux de mise en œuvre, BigInteger le supportera sans problème. Le problème est probablement de savoir comment l'OP essaie de faire l'initialisation. – Peter

+3

À l'avenir, au lieu de dire "il est toujours trop grand", il suffit de copier-coller le message d'erreur exact que vous voyez. Pour moi, le compilateur dit 'nombre entier trop grand: 602200000000000000000000'. –

Répondre

5

Tout d'abord, vous devez vérifier votre livre de texte physique/chimie.

Le numéro d'Avogadro n'est pas 602,200,000,000,000,000,000,000. C'est environ 6,022 x 10 . Le mot clé est "approximativement". Le nombre est une valeur mesurée empiriquement.

(Selon Wikipedia, la meilleure approximation courante est 6,022140857 (74) x 10 mol-1, et l'erreur relative est de 1,2 +/- × 10 -8 .)

Étant donné que le nombre n'est connu qu'avec une précision d'environ 8 décimales, le type Java double est un type approprié pour le représenter.Par conséquent, j'utiliser

final double AVOGADROS_CONSTANT = 6.02214085774E23; 

De toute évidence, ni int ou long peut représenter ce nombre. Un float pourrait, mais pas avec assez de précision (en supposant que nous utilisons la meilleure valeur mesurée disponible). BigInteger est une possibilité, mais elle est conceptuellement erronée car nous n'avons pas de valeur entière exacte pour la constante.


maintenant à vos problèmes apparents avec la déclaration constante (diversement) un double, un long et un BigInteger.

Je pense que vous avez fait quelque chose comme ceci:

double a = 602200000000000000000000; 

et ainsi de suite. Cela ne va pas fonctionner, mais la raison pour laquelle cela ne fonctionnera pas doit être expliquée. Le problème est que le nombre est fourni en tant que littéral int. Un int ne peut pas être si gros. La plus grande valeur possible int est 2 - 1 ... qui est un peu plus grande que 2 x 10 .

C'est ce dont se plaignait le compilateur Java. Le littéral est trop grand pour être un int.

Il est trop grand pour long littéral aussi bien. (Faites le calcul.)

Mais ce n'est pas trop grand pour un littéral double ... à condition que vous l'écrivez correctement.

La solution utilisant BigInteger(String) fonctionne car elle contourne le problème de représentation du nombre en tant que littéral numérique en utilisant une chaîne à la place et en l'analysant au moment de l'exécution. C'est OK du point de vue de la langue, mais (IMO) faux parce que la précision supplémentaire est une illusion.

13

Passez-le au constructeur BigInteger en tant que String, et cela fonctionne très bien.

BigInteger a = new BigInteger("602200000000000000000000"); 
a = a.multiply(new BigInteger("2")); 
System.out.println(a); 

Sortie: 1204400000000000000000000

+0

Merci, semble que la plupart de mon programme sera défini dans les arguments de chaîne. Mais pourquoi peut-il le représenter comme une chaîne et pourtant il ne peut pas en tant qu'entier? –

+1

@AntonioAguilar c'est parce que quand vous essayez de le passer au constructeur BigInteger comme 'BigInteger a = new BigInteger (602200000000000000000000);' alors d'abord ce nombre est analysé comme un int. Évidemment, bien que cela ne rentre pas dans un int, bien que cela puisse certainement convenir à un BigInt. Pour contourner cela, vous passez le numéro en tant que chaîne. Voir la réponse de Dukeling pour plus de détails. – Rishav

5

Vous pouvez utiliser la notation E pour écrire la notation scientifique:

double a = 6.022e23; 
3

Le problème est la façon dont vous essayez de créer (le plus probable), non parce que ça ne peut pas aller.

Si vous avez juste un littéral dans votre code (même si vous essayez de l'affecter à un double ou long), this is first treated as an integer (avant d'être converti au type qu'il a besoin d'être), et le numéro que vous avez peut » t entrer dans un nombre entier.

// Even though this number can fit into a long, it won't compile, because it's first treated 
// as an integer. 
long l = 1234567889; 

Pour créer une longue, vous pouvez ajouter à votre numéro L, donc 602200000000000000000000L, même si elle ne rentre pas dans une longue soit - the max value is 263-1.

Pour créer un double, vous pouvez ajouter .0 à votre numéro, si 602200000000000000000000.0 (ou 6.022e23 comme Guffa suggéré), bien que vous ne devriez pas utiliser si vous voulez des valeurs précises, comme vous risquez de perdre une certaine précision en raison de la façon dont il stocke la valeur.

Pour créer un BigInteger, vous pouvez utiliser the constructor taking a string parameter:

new BigInteger("602200000000000000000000");