Pour un petit projet (Problème 10 Project Euler) J'ai essayé de résumer tous les nombres premiers en dessous de 2 millions. J'ai donc utilisé une méthode de force brute et itéré de 0 à 2'000'000 et vérifiée si le nombre est une prime. Si c'est le cas, je l'ai ajouté à la somme: Le résultat de ce calcul est 1179908154, mais cela est incorrect. J'ai donc changé INT vers BigInteger et je reçois maintenant la bonne somme 142913828922. De toute évidence, la gamme d'INT a été débordée. Mais pourquoi Java ne peut-il pas me dire ça? (par exemple, une exception) p> p>
5 Réponses :
Parce que c'est concevable que vous souhaitiez que cela se comporte de manière entière traditionnelle. Les exceptions sont réservées aux choses qui sont définitivement et irrévocablement erronées. P>
"Les opérateurs entier intégrés ne font pas
indiquer le débordement ou le débordement dans tout
manière. Les seuls opérateurs numériques qui
peut jeter une exception (§11) sont la
Opérateur de division entier / (§15.17.2)
et l'opérateur de reste entier%
(§15.17.3), qui jettent un
Arithméticepxception si la main droite
l'opérande est zéro. " P>
blockQuote>
( http: //java.sun. com / docs / livres / jls / second_edition / html / typevalues.doc.html ) p>
Ensuite, je devrais toujours tester avant d'ajouter un certain nombre de la plage est dépassée?
Si vous savez que votre numéro peut être grand, vous devez utiliser une classe «plus grande» pour le gérer.
Je suis d'accord avec Felipe. Si vous avez besoin d'une garantie que x + 1> x pour les valeurs ci-dessus la gamme d'entier, utilisez BigInteger. Si vous utilisez un Int pour une autre raison, vous devriez être correct.
@Jim Kiley - ou un long code> / long code>, pour les chiffres ci-dessus la gamme d'entier mais définitivement toujours dans la plage des longs ( long.max_long code> ~ = = 2 ^ 63), serait un remplacement plus naturel. Cela ne veut pas dire que BigInteger code> n'est pas utile, mais ils sont un peu plus spécialisés.
@Andrzej Vous êtes bien sûr correct; Dans ma défense, le café est faible et je n'ai donc pas été entièrement réveillé quand j'ai écrit ça.
car il est concevable que vous souhaitiez que cela se compare de la mode entière traditionnelle. Code> Il est concevable que vous voudriez à propos de toutes les caractéristiques de commodité pour se comporter dans les méthodes traditionnelles (par exemple, des limites de la matrice excessives) . La raison pour laquelle nous ne sommes pas, c'est que Faire le cas commun La valeur par défaut est beaucoup plus importante que la puissance absolue b>.
Outre ce que Jim dit, la vérification des conditions telles que le débordement ajouterait une pénalité de performance à tout calcul effectué avec des entiers, ce qui ferait des programmes qui font beaucoup de calculs beaucoup plus lents. P>
Et que i> est la vraie raison pour laquelle cela est fait de cette façon. C'est aussi pourquoi nous avons des primitives!
@Vuntic Je ne pense pas que ce soit la vraie raison pour laquelle nous avons des primitives - dans d'autres langues (Scala, par exemple), le compilateur est suffisamment intelligent pour utiliser des entiers natifs lorsque vous utilisez par exemple la classe INT. En d'autres termes, si le compilateur Java aurait été rendu plus intelligent, des types de données primitifs n'auraient pas besoin d'avoir été exposés dans le langage de programmation.
1) Vous comparez 2 langues dont les origines ont plus de 15 ans d'intervalle. 2) Un compilateur Java n'est pas autorisé à être "intelligent" et à remplacer un type avec un autre ... à moins que la JLS sanctionne cela. (Les règles d'affectation définitive sont un autre exemple où le compilateur Java n'est pas autorisé à être "intelligent".)
Être au courant de INTEGER.MAX_Value est toujours utile :) p>
L'autre raison est que vous pouvez le faire vérifier très facilement et rapidement.
if (sum+i < sum) {
throw new AritchmeticException();
}
Parce que notre profession valorise la performance sur l'exactitude. ; ( p>
Utilisation de BigInteger Par défaut, et seul raisonnement s'il est acceptable, d'utiliser Long ou Int si la performance est un problème réel, aiderait à éviter de tels problèmes. p>
En fait, parce que les concepteurs de langue Java veulent donner aux programmeurs la possibilité de valoriser la performance sur l'exactitude.
En écart, BigInteger est surchargée et longtemps aurait bien fonctionné.
Pourquoi n'utilisez-vous pas un tamis d'eratosthènes au lieu de brute la forcer?
@Djclayworth: mal essayer @coolbeans: la force brute est assez rapide, il ne prend qu'une fraction d'une seconde
En règle générale, les calculs numériques itératifs doivent être analysés pour débordement, perte de flux, perte de précision, etc. Il s'agit d'un problème non trivial en mathématiques. Les compilateurs ne vont donc pas résoudre pour vous à tout moment.
Merci. Appris quelque chose de nouveau!