Erreur fatale Java JRE: trop de multiplications

J’essayais de tester la vitesse de Math.pow() contre la multiplication “à la main” et suis tombé sur cette erreur:

Une erreur fatale a été détectée par l’environnement d’exécution Java:

EXCEPTION_ACCESS_VIOLATION (0xc0000005) sur pc = 0x000000005ac46888, pid = 1508, tid = 6016

Version JRE: Environnement d’exécution SE Java (TM) (8.0_25-b18) (version 1.8.0_25-b18)
Ordinateur virtuel Java: Ordinateur virtuel serveur Java HotSpot (TM) 64 bits (oops compressés en mode mixte Windows-amd64 25.25-b02)
Cadre problématique:
V [jvm.dll + 0x496888]

Échec de l’écriture du core dump. Les mini-pompes ne sont pas activées par défaut sur les versions client de Windows

Code le générant:

 long t = System.nanoTime(); for (int i = 0; i < 10000000; i++) { double val = i*i*i*i*i /* 256 times *i */ *i*i*i; sum ^= Double.doubleToLongBits(val); } System.out.println((System.nanoTime() - t) / 10000000); 

Je comprends que c’est vraiment un cas extrême, mais c’est quand même un code valide et que la pire chose qui pourrait arriver devrait être d’avoir Inf dans la valeur, et non de crash JRE. Est-ce vraiment le comportement standard décrit par oracle ou tout simplement un bogue que personne ne veut corriger simplement parce que si vous le voyez, vous êtes vraiment une mauvaise personne.

Pour l’enregistrement avec NetBeans 8.0.2

MISE À JOUR 1

Il semble que le problème soit de l’ampleur du nombre multiplié.

 long t = System.nanoTime(); for(int j = 0; j < 10000000; j++) { int i = j % 50; double val = i*i*i*i*i /* 256 times *i */ *i*i*i; sum ^= Double.doubleToLongBits(val); } System.out.println((System.nanoTime() - t) / 10000000); 

passera très bien.

MISE À JOUR 2

J’ai essayé de l’exécuter depuis la console avec

 java version "1.8.0_45" Java(TM) SE Runtime Environment (build 1.8.0_45-b15) Java HotSpot(TM) 64-Bit Server VM (build 25.45-b02, mixed mode) 

et passé très bien, donc je suppose que cela doit être soit un problème avec cet JRE spécifique, soit avec NetBeans.

Cela ressemble vraiment à un bug JVM pour moi. C’est plus approprié comme rapport de bogue qu’une question sur SO. Voir http://bugreport.java.com/

Cela fonctionne bien pour moi. Où le problème se produit pour vous? Isolez le problème en réduisant les multiplications ou le nombre de boucles. Est-ce que ça marche avec 50 multiplications?

 long sum=0; long t = System.nanoTime(); for (int i = 1; i < 10000000; i++) { double val = i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i *i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i *i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i*i; // set of 10 *i*i*i*i*i*i*i*i*i*i sum ^= Double.doubleToLongBits(val); } System.out.println(sum); System.out.println((System.nanoTime() - t) / 10000000); 

jre1.8.0_51

sortie:

  -32067153335156736
     614 

Même multiplier par 10 itérations supplémentaires fonctionne mais est vraiment lent. heure 6020

Essayez d’utiliser BigInteger.

 import java.math.BigInteger; public class hackerrank { public static void main (Ssortingng args[]){ BigInteger x = new BigInteger("10000000"); BigInteger sum = BigInteger.ZERO; long t = System.nanoTime(); for (BigInteger i = BigInteger.ONE; i.compareTo(x) == -1; i = i.add(BigInteger.ONE)) { BigInteger j = i.remainder(new BigInteger("50")); BigInteger val = j.pow(256); sum = sum.xor(val); } System.out.println((System.nanoTime() - t) / 10000000); } } 

Sortie: 4083