2010-10-18 8 views
3

code:analyser longtemps nombre négatif

public class Main{ 
    public static void main(String[] a){ 
     long t=24*1000*3600; 
     System.out.println(t*25); 
     System.out.println(24*1000*3600*25); 
    } 
} 

Cette impression:

2160000000 

-2134967296 

Pourquoi?


Merci pour toutes les réponses.

La seule façon d'utiliser L après le numéro?

J'ai essayé le (long)24*1000*3600*25 mais c'est aussi négatif.

+1

Si vous avez trouvé une réponse qui a résolu votre problème, assurez-vous de voter comme un accepté répondez (en cliquant sur la coche sous la partition). –

+0

Bonjour hguser. Par '(long) 24 * 1000 * 3600 * 25' vous convertissez le résultat, qui est' -2134967296', en un long, qui est '-2134967296L'. Vous pouvez en effet utiliser (long) au lieu de L mais avec des parenthèses supplémentaires: '((long) 24) * 1000 * 3600 * 25'. Cependant, L est exactement fait pour ce cas, et il est même possible que le compilateur génère un code octet différent: 24L est un littéral de type long, tandis que (long) 24 est un littéral de type int qui doit d'abord être converti en un long (mais espérons que le compilateur optimise cela). – chiccodoro

Répondre

11

Pour expliquer clairement,

System.out.println(24*1000*3600*25); 

Dans la déclaration ci-dessus sont en fait int littéraux. Pour les traiter comme un littéral long, vous devez suffixer ceux avec L.

System.out.println(24L*1000L*3600L*25L); 

caveat, un petit l suffit aussi, mais qui ressemble à du capital I ou 1, parfois. Capital I n'a pas beaucoup de sens ici, mais en lisant cela comme 1 peut vraiment donner du mal. En outre, Même en suffisant une seule valeur avec L fera le résultat long.

+1

un petit «l» ressemble plus au chiffre «1» – dogbane

+1

@dogbane: Oh! Ouais, dans la plupart des éditeurs de programmation, son plus similaire à '1' .Mais je ne me trompe pas en suggérant cela, je suppose.Il arrive quand votre police est' Arial'.Essayez cela, les deux seraient idem l'un de l'autre –

+0

Notez que seulement les nombres ne doivent pas être longs; 24L * 1000 * 36000 * 25 fonctionnera aussi parce que le résultat final sera la longueur de la longueur de l'équation maximum, dans ce cas c'est 'long'. Cela est également vrai dans presque tous les langages de programmation. Notez que vous aurez parfois besoin d'un double pour ne perdre aucun bit, ex: (long) (1d * someLong * someLong/someLong) –

6

Dans le premier cas, vous imprimez un long mais dans le second, vous l'imprimez sous la forme int. La plage 0-est comprise entre: -2^31 et 2^31 - 1, ce qui est juste au-dessous de ce que vous calculez (int max: 2147483647 vous: 2160000000), donc vous débordez l'int à la plage négative.

Il est possible de forcer la seconde à utiliser long ainsi:

System.out.println(24L*1000*3600*25); 
18

vous avez atteint le maximum du type int qui est Integer.MAX_VALUE ou 2^31-1. Il s'est enveloppé à cause de cela, vous montrant ainsi un nombre négatif.

Pour une explication immédiate de ce sujet, voir cette bande dessinée:

alt text

+6

+1 pour xkcd .... –

+0

Drôle, cependant, je ne peux pas comprendre cette bande dessinée .. :(Mais je sais peut-être le sens, il montre le débordement de données? N'est-ce pas? – hguser

+0

Oui, il montre le nombre de moutons monter jusqu'à 32,767, puis quand le débordement se produit, le compte continue, mais en partant de la limite inférieure, pour moi la métaphore du cercle aide beaucoup à comprendre ceci. –

2

littéraux intégrale sont traités comme le type int par défaut. 24*1000*3600*25 est supérieur à Integer.MAX_VALUE donc déborde et évalue à -2134967296. Vous devez faire explicitement l'un d'eux un long en utilisant le suffixe L pour obtenir le bon résultat:

System.out.println(24L*1000*3600*25); 
3

Vous devez suffixer les chiffres avec 'l'. Vérifiez l'extrait ci-dessous:

public static void main(String[] a){ 
     long t=24*1000*3600; 
     System.out.println(t*25); 
     System.out.println(24l*1000l*3600l*25l); 
    } 
1

Si vous voulez faire des opérations mathématiques avec de grandes valeurs numériques sans plus fluide, essayez la classe BigDecimal.

Disons que je veux multiplier

200000000 * 2,000,000,000,000,000,000L * 20.000.000

int testValue = 200000000; 
System.out.println("After Standard Multiplication = " + 
                 testValue * 
                 2000000000000000000L * 
                 20000000); 

La valeur de l'opération sera -4176287866323730432, ce qui est incorrect. En utilisant la classe BigDecimal, vous pouvez éliminer les bits déposés et obtenir le résultat correct.

int testValue = 200000000;   
System.out.println("After BigDecimal Multiplication = " + 
           decimalValue.multiply(
           BigDecimal.valueOf(2000000000000000000L).multiply(
           BigDecimal.valueOf(testValue)))); 

Après avoir utilisé le BigDecimal, la multiplication renvoie le résultat correct qui est

0
(int)Long.valueOf("2345678901").longValue(); 
+2

Pouvez-vous expliquer comment '(int)' a du sens dans votre exemple? – Tom