Pourquoi Java pense-t-il que le produit de tous les nombres compris entre 10 et 99 est 0?

Le bloc de codes suivant donne la sortie comme 0.

public class HelloWorld{ public static void main(Ssortingng []args){ int product = 1; for (int i = 10; i <= 99; i++) { product *= i; } System.out.println(product); } } 

S’il vous plaît quelqu’un peut-il expliquer pourquoi cela se produit?

    Voici ce que le programme fait à chaque étape:

      1 * 10 = 10 10 * 11 = 110 110 * 12 = 1320 1320 * 13 = 17160 17160 * 14 = 240240 240240 * 15 = 3603600 3603600 * 16 = 57657600 57657600 * 17 = 980179200 980179200 * 18 = 463356416 463356416 * 19 = 213837312 213837312 * 20 = -18221056 -18221056 * 21 = -382642176 -382642176 * 22 = 171806720 171806720 * 23 = -343412736 -343412736 * 24 = 348028928 348028928 * 25 = 110788608 110788608 * 26 = -1414463488 -1414463488 * 27 = 464191488 464191488 * 28 = 112459776 112459776 * 29 = -1033633792 -1033633792 * 30 = -944242688 -944242688 * 31 = 793247744 793247744 * 32 = -385875968 -385875968 * 33 = 150994944 150994944 * 34 = 838860800 838860800 * 35 = -704643072 -704643072 * 36 = 402653184 402653184 * 37 = 2013265920 2013265920 * 38 = -805306368 -805306368 * 39 = -1342177280 -1342177280 * 40 = -2147483648 -2147483648 * 41 = -2147483648 -2147483648 * 42 = 0 0 * 43 = 0 0 * 44 = 0 vvvvvvvvvvvvvvvvvvvvvvvvvvvvvv vvvvvvvvvvvvvvvvvvvvvvvvvvvvvv 0 * 97 = 0 0 * 98 = 0 

    Notez que sur certaines étapes, la multiplication se traduit par un nombre plus petit (980179200 * 18 = 463356416) ou un signe incorrect (213837312 * 20 = -18221056), indiquant qu’il y avait un dépassement d’entier. Mais d’où vient le zéro? Continuer à lire.

    En gardant à l’esprit que le type de données int est un entier signé à deux bits de 32 bits , voici une explication de chaque étape:

     Operation Result(1) Binary Representation(2) Result(3) ---------------- ------------ ----------------------------------------------------------------- ------------ 1 * 10 10 1010 10 10 * 11 110 1101110 110 110 * 12 1320 10100101000 1320 1320 * 13 17160 100001100001000 17160 17160 * 14 240240 111010101001110000 240240 240240 * 15 3603600 1101101111110010010000 3603600 3603600 * 16 57657600 11011011111100100100000000 57657600 57657600 * 17 980179200 111010011011000101100100000000 980179200 980179200 * 18 17643225600 100 00011011100111100100001000000000 463356416 463356416 * 19 8803771904 10 00001100101111101110011000000000 213837312 213837312 * 20 4276746240 11111110111010011111100000000000 -18221056 -18221056 * 21 -382642176 11111111111111111111111111111111 11101001001100010101100000000000 -382642176 -382642176 * 22 -8418127872 11111111111111111111111111111110 00001010001111011001000000000000 171806720 171806720 * 23 3951554560 11101011100001111111000000000000 -343412736 -343412736 * 24 -8241905664 11111111111111111111111111111110 00010100101111101000000000000000 348028928 348028928 * 25 8700723200 10 00000110100110101000000000000000 110788608 110788608 * 26 2880503808 10101011101100010000000000000000 -1414463488 -1414463488 * 27 -38190514176 11111111111111111111111111110111 00011011101010110000000000000000 464191488 464191488 * 28 12997361664 11 00000110101101000000000000000000 112459776 112459776 * 29 3261333504 11000010011001000000000000000000 -1033633792 -1033633792 * 30 -31009013760 11111111111111111111111111111000 11000111101110000000000000000000 -944242688 -944242688 * 31 -29271523328 11111111111111111111111111111001 00101111010010000000000000000000 793247744 793247744 * 32 25383927808 101 11101001000000000000000000000000 -385875968 -385875968 * 33 -12733906944 11111111111111111111111111111101 00001001000000000000000000000000 150994944 150994944 * 34 5133828096 1 00110010000000000000000000000000 838860800 838860800 * 35 29360128000 110 11010110000000000000000000000000 -704643072 -704643072 * 36 -25367150592 11111111111111111111111111111010 00011000000000000000000000000000 402653184 402653184 * 37 14898167808 11 01111000000000000000000000000000 2013265920 2013265920 * 38 76504104960 10001 11010000000000000000000000000000 -805306368 -805306368 * 39 -31406948352 11111111111111111111111111111000 10110000000000000000000000000000 -1342177280 -1342177280 * 40 -53687091200 11111111111111111111111111110011 10000000000000000000000000000000 -2147483648 -2147483648 * 41 -88046829568 11111111111111111111111111101011 10000000000000000000000000000000 -2147483648 -2147483648 * 42 -90194313216 11111111111111111111111111101011 00000000000000000000000000000000 0 0 * 43 0 0 0 vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv 0 * 98 0 0 0 
    1. est le bon résultat
    2. est la représentation interne du résultat (64 bits sont utilisés à des fins d’illustration)
    3. est le résultat représenté par le complément à deux des 32 bits inférieurs

    Nous soaps que multiplier un nombre par un nombre pair:

    • déplace les bits vers la gauche et ajoute zéro bit vers la droite
    • donne un nombre pair

    Donc, fondamentalement, votre programme multiplie plusieurs fois un nombre pair avec un autre nombre, ce qui met à zéro les bits de résultat à partir de la droite.

    PS: Si les multiplications n’impliquent que des nombres impairs, le résultat ne deviendra pas nul.

    La multiplication par ordinateur se produit réellement modulo 2 ^ 32. Une fois que vous avez accumulé suffisamment de puissances de deux dans le multiplicande, toutes les valeurs seront alors 0.

    Nous avons ici tous les nombres pairs de la série, ainsi que la puissance maximale de deux qui divise le nombre et la puissance cumulée de deux.

     num max2 total 10 2 1 12 4 3 14 2 4 16 16 8 18 2 9 20 4 11 22 2 12 24 8 15 26 2 16 28 4 18 30 2 19 32 32 24 34 2 25 36 4 27 38 2 28 40 8 31 42 2 32 

    Le produit jusqu’à 42 est égal à x * 2 ^ 32 = 0 (mod 2 ^ 32). La séquence des puissances de deux est liée aux codes Gray (entre autres) et apparaît sous la forme https://oeis.org/A001511 .

    EDIT: pour voir pourquoi les autres réponses à cette question sont incomplètes, considérez le fait que le même programme, limité uniquement aux entiers impairs, ne convergerait pas vers 0, malgré tous les débordements.

    Cela ressemble à un dépassement d’entier .

    Regarde ça

     BigDecimal product=new BigDecimal(1); for(int i=10;i<99;i++){ product=product.multiply(new BigDecimal(i)); } System.out.println(product); 

    Sortie:

     25977982938941930515945176761070443325092850981258133993315252362474391176210383043658995147728530422794328291965962468114563072000000000000000000000 

    La sortie n'est plus une valeur int . Ensuite, vous aurez une mauvaise valeur en raison du débordement.

    S'il déborde, il retourne à la valeur minimale et continue à partir de là. S'il est sous-estimé, il revient à la valeur maximale et continue à partir de là.

    Plus d' infos

    Modifier

    Changeons votre code comme suit

     int product = 1; for (int i = 10; i < 99; i++) { product *= i; System.out.println(product); } 

    Out mis:

     10 110 1320 17160 240240 3603600 57657600 980179200 463356416 213837312 -18221056 -382642176 171806720 -343412736 348028928 110788608 -1414463488 464191488 112459776 -1033633792 -944242688 793247744 -385875968 150994944 838860800 -704643072 402653184 2013265920 -805306368 -1342177280 -2147483648 -2147483648>>>binary representation is 11111111111111111111111111101011 10000000000000000000000000000000 0 >>> here binary representation will become 11111111111111111111111111101011 00000000000000000000000000000000 ---- 0 

    C’est à cause du débordement d’entier. Lorsque vous multipliez plusieurs nombres pairs, le nombre binary reçoit beaucoup de zéros. Lorsque vous avez plus de 32 zéros à droite pour un int , il passe à 0 .

    Pour vous aider à visualiser ceci, voici les multiplications en hexadécimal calculées sur un type de nombre qui ne débordera pas. Voyez comment les zéros à la fin grandissent lentement et notez qu’un int est constitué des 8 derniers chiffres hexadécimaux. Après multiplication par 42 (0x2A), tous les 32 bits d’un int sont des zéros!

      1 (int: 00000001) * 0A = A (int: 0000000A) * 0B = 6E (int: 0000006E) * 0C = 528 (int: 00000528) * 0D = 4308 (int: 00004308) * 0E = 3AA70 (int: 0003AA70) * 0F = 36FC90 (int: 0036FC90) * 10 = 36FC900 (int: 036FC900) * 11 = 3A6C5900 (int: 3A6C5900) * 12 = 41B9E4200 (int: 1B9E4200) * 13 = 4E0CBEE600 (int: 0CBEE600) * 14 = 618FEE9F800 (int: FEE9F800) * 15 = 800CE9315800 (int: E9315800) * 16 = B011C0A3D9000 (int: 0A3D9000) * 17 = FD1984EB87F000 (int: EB87F000) * 18 = 17BA647614BE8000 (int: 14BE8000) * 19 = 25133CF88069A8000 (int: 069A8000) * 1A = 3C3F4313D0ABB10000 (int: ABB10000) * 1B = 65AAC1317021BAB0000 (int: 1BAB0000) * 1C = B1EAD216843B06B40000 (int: 06B40000) * 1D = 142799CC8CFAAFC2640000 (int: C2640000) * 1E = 25CA405F8856098C7B80000 (int: C7B80000) * 1F = 4937DCB91826B2802F480000 (int: 2F480000) * 20 = 926FB972304D65005E9000000 (int: E9000000) * 21 = 12E066E7B839FA050C309000000 (int: 09000000) * 22 = 281CDAAC677B334AB9E732000000 (int: 32000000) * 23 = 57BF1E59225D803376A9BD6000000 (int: D6000000) * 24 = C56E04488D526073CAFDEA18000000 (int: 18000000) * 25 = 1C88E69E7C6CE7F0BC56B2D578000000 (int: 78000000) * 26 = 43C523B86782A6DBBF4DE8BAFD0000000 (int: D0000000) * 27 = A53087117C4E76B7A24DE747C8B0000000 (int: B0000000) * 28 = 19CF951ABB6C428CB15C2C23375B80000000 (int: 80000000) * 29 = 4223EE1480456A88867C311A3DDA780000000 (int: 80000000) * 2A = AD9E50F5D0B637A6610600E4E25D7B00000000 (int: 00000000) 

    Quelque part au milieu, vous obtenez 0 comme produit. Donc, votre produit entier sera 0.

    Dans ton cas :

     for (int i = 10; i < 99; i++) { if (product < Integer.MAX_VALUE) System.out.println(product); product *= i; } // System.out.println(product); System.out.println(-2147483648 * EvenValueOfi); // --> this is the culprit (Credits : Kocko's answer ) O/P : 1 10 110 1320 17160 240240 3603600 57657600 980179200 463356416 213837312 -18221056 -382642176 171806720 -343412736 348028928 110788608 -1414463488 464191488 112459776 -1033633792 -944242688 793247744 -385875968 150994944 838860800 -704643072 402653184 2013265920 -805306368 -1342177280 --> Multiplying this and the current value of `i` will also give -2147483648 (INT overflow) -2147483648 --> Multiplying this and the current value of `i` will also give -2147483648 (INT overflow) -2147483648 -> Multiplying this and the current value of 'i' will give 0 (INT overflow) 0 0 0 

    Chaque fois que vous multipliez la valeur actuelle de i par le nombre, vous obtenez 0 en sortie.

    Étant donné que la plupart des points de réponses existants sur les détails d’implémentation de Java et les résultats de débogage, jetons un coup d’oeil aux mathématiques derrière la multiplication binary pour vraiment répondre à la raison.

    Le commentaire de @kasperd va dans la bonne direction. Supposons que vous ne multipliez pas directement avec le nombre, mais avec les facteurs premiers de ce nombre. Que beaucoup de chiffres auront 2 comme facteur primordial. En binary, cela équivaut à un décalage vers la gauche. Par commutativité on peut multiplier par des facteurs premiers de 2 d’abord. Cela signifie que nous faisons juste un changement de gauche.

    Lorsque vous examinez les règles de multiplication binary, le seul cas où un 1 entraîne une position de chiffre spécifique est lorsque les deux valeurs d’opérande sont une.

    Ainsi, un décalage à gauche a pour effet d’augmenter la position de bit la plus faible d’un 1 lorsque le résultat est multiplié.

    Puisque entier ne contient que les bits les plus bas, ils seront tous mis à 0 lorsque le facteur premier 2 est assez souvent contenu dans le résultat.

    Notez que la représentation du complément à deux n’est pas intéressante pour cette parsing, puisque le signe du résultat de la multiplication peut être calculé indépendamment du nombre résultant. Cela signifie que si la valeur déborde et devient négative, les bits de poids faible sont représentés par 1, mais pendant la multiplication, ils sont à nouveau considérés comme 0.

    Si je lance ce code Ce que je reçois tous –

      1 * 10 = 10 10 * 11 = 110 110 * 12 = 1320 1320 * 13 = 17160 17160 * 14 = 240240 240240 * 15 = 3603600 3603600 * 16 = 57657600 57657600 * 17 = 980179200 980179200 * 18 = 463356416 <- Integer Overflow (17643225600) 463356416 * 19 = 213837312 213837312 * 20 = -18221056 -18221056 * 21 = -382642176 -382642176 * 22 = 171806720 171806720 * 23 = -343412736 -343412736 * 24 = 348028928 348028928 * 25 = 110788608 110788608 * 26 = -1414463488 -1414463488 * 27 = 464191488 464191488 * 28 = 112459776 112459776 * 29 = -1033633792 -1033633792 * 30 = -944242688 -944242688 * 31 = 793247744 793247744 * 32 = -385875968 -385875968 * 33 = 150994944 150994944 * 34 = 838860800 838860800 * 35 = -704643072 -704643072 * 36 = 402653184 402653184 * 37 = 2013265920 2013265920 * 38 = -805306368 -805306368 * 39 = -1342177280 -1342177280 * 40 = -2147483648 -2147483648 * 41 = -2147483648 -2147483648 * 42 = 0 <- produce 0 0 * 43 = 0 

    Integer Overflow cause -

     980179200 * 18 = 463356416 (should be 17643225600) 17643225600 : 10000011011100111100100001000000000 <-Actual MAX_Integer : 1111111111111111111111111111111 463356416 : 0011011100111100100001000000000 <- 32 bit Integer 

    Produire 0 cause -

     -2147483648 * 42 = 0 (should be -90194313216) -90194313216: 1010100000000000000000000000000000000 <- Actual MAX_Integer : 1111111111111111111111111111111 0 : 00000000000000000000000000000000 <- 32 bit Integer 

    Finalement, le calcul déborde et finalement ce débordement conduit à un produit de zéro; cela se product == -2147483648 lorsque le product == -2147483648 et i == 42 . Essayez ce code pour le vérifier vous-même (ou exécutez le code ici ):

     import java.math.BigInteger; class Ideone { public static void main (Ssortingng[] args) throws java.lang.Exception { System.out.println("Result: " + (-2147483648 * 42)); } } 

    Une fois qu’il est à zéro, il rest bien sûr zéro. Voici un code qui produira un résultat plus précis (vous pouvez exécuter le code ici ):

     import java.math.BigInteger; class Ideone { public static void main (Ssortingng[] args) throws java.lang.Exception { BigInteger p = BigInteger.valueOf(1); BigInteger start = BigInteger.valueOf(10); BigInteger end = BigInteger.valueOf(99); for(BigInteger i = start; i.compareTo(end) < 0; i = i.add(BigInteger.ONE)){ p = p.multiply(i); System.out.println("p: " + p); } System.out.println("\nProduct: " + p); } } 

    C’est un dépassement d’entier.

    Le type de données int est de 4 octets ou 32 bits. Par conséquent, les nombres supérieurs à 2 ^ (32 – 1) – 1 (2 147 483 647) ne peuvent pas être stockés dans ce type de données. Vos valeurs numériques seront incorrectes.

    Pour les très grands nombres, vous voudrez importer et utiliser la classe java.math.BigInteger:

     BigInteger product = BigInteger.ONE; for (long i = 10; i < 99; i++) product = product.multiply(BigInteger.valueOf(i)); System.out.println(product.toString()); 

    REMARQUE: Pour les valeurs numériques encore trop grandes pour le type de données int, mais suffisamment petites pour tenir dans les 8 octets (valeur absolue inférieure ou égale à 2 ^ (64-1) - 1), vous devez probablement utiliser la primitive long .

    Les problèmes de pratique de HackerRank (www.hackerrank.com), tels que la section sur la pratique des algorithmes ( https://www.hackerrank.com/domains/algorithms/warmup ), comprennent de très bonnes questions à grand nombre qui expliquent comment Réfléchissez au type de données approprié à utiliser.