2010-06-19 4 views
11

J'ai fait quelques recherches sur google, mais je n'arrive pas à trouver ce que je cherche. J'essaie de trouver des informations détaillées sur le fonctionnement de l'arithmétique en Java. Par exemple, si vous ajoutez deux longs ensemble est-ce en utilisant le même opérateur d'addition qui est utilisé lors de l'addition de deux entiers? De plus, ce qui se passe sous le capot lorsque vous mélangez et désire ardemment ints dans les expressions arithmétiques comme ceci:Java arithmétique int contre long

long result; 
long operand a = 1; 
int operand b = 999999999; 

result = a + b; 

Si quelqu'un pouvait faire la lumière sur ce ou poster des liens vers des articles pertinents qui seraient génial. Merci!

EDIT: Merci pour les réponses à ce jour. En outre, est-il sûr d'effectuer l'arithmétique avec différentes primitives aussi longtemps que vous assignez dans une variable du type primitif le plus large dans votre expression?

+2

Ce n'est pas un forum, il n'est pas vraiment transparent pour les personnes qui ont répondu à votre question que vous avez un suivi. Comme pour votre edit si: Java ne vous permettra pas d'affecter le résultat d'une opération à une variable si la variable n'est pas d'un type primitif "large" assez pour le contenir.Autrement dit, vous ne pouvez pas assigner le résultat de "0L + 1" à un int sans lancer spécifiquement un int. –

+0

Ah ok, c'est logique. Merci pour le suivi. – BordrGuy108

+0

Ce n'est pas tout à fait sûr car de nombreuses opérations peuvent entraîner un débordement ou un débordement. essayez Long.MAX_VALUE + 1 Cependant, il compilera toujours si vous affectez au type le plus large. –

Répondre

15

Lorsque vous mélangez des types, int est automatiquement élargi à un long, puis les deux longs sont ajoutés pour produire le résultat. Le java language spec a de bons exemples pour les opérations contenant différents types primatifs.

Plus précisément, ce sont les types de chaque volonté primative élargissement de sans nécessiter un casting:

  • octet short, int, long, float ou double
  • court int, long, float, ou à double
  • char int, long, float ou double
  • int à long, float ou double
  • à long flotter ou double flotteur
  • à à double
+0

Je suppose que cela va réparer le lien brisé: http://docs.oracle.com/javase/specs/jls/se5.0/html/conversions.html#5.6 – Chris

7

Voir: Conversions and promotions

D'après cela, votre int est promu long puis est évaluée. Il en est de même avec int + double et le reste des primitives. c'est à dire.

System.out(1 + 2.0);// prints 3.0 a double 

En ce qui concerne l'opérateur d'addition je suis à peu près c'est le même, mais je n'ai pas de référence de celui-ci.

Une vue rapide de la source du compilateur révèle qu'ils sont différents.

A savoir iadd pour l'addition int et ladd longtemps plus:

Voir cet exemple de code:

$cat Addition.java 
public class Addition { 
    public static void main(String [] args) { 
     int a = Integer.parseInt(args[0]); 
     long b = Long.parseLong(args[0]); 
     // int addition 
     int c = a + a; 
     // long addition 
     long d = a + b; 
    } 
} 
$javac Addition.java 
$ 

Lorsque compilé le code octet généré est ceci:

$javap -c Addition 
Compiled from "Addition.java" 
public class Addition extends java.lang.Object{ 
public Addition(); 
    Code: 
    0: aload_0 
    1: invokespecial #1; //Method java/lang/Object."<init>":()V 
    4: return 

public static void main(java.lang.String[]); 
    Code: 
    0: aload_0 
    1: iconst_0 
    2: aaload 
    3: invokestatic #2; //Method java/lang/Integer.parseInt:(Ljava/lang/String;)I 
    6: istore_1 
    7: aload_0 
    8: iconst_0 
    9: aaload 
    10: invokestatic #3; //Method java/lang/Long.parseLong:(Ljava/lang/String;)J 
    13: lstore_2 
    14: iload_1 
    15: iload_1 
    16: iadd 
    17: istore 4 
    19: iload_1 
    20: i2l 
    21: lload_2 
    22: ladd 
    23: lstore 5 
    25: return 

} 

Regardez ligne 16 il est dit: iadd (pour int plus) alors que la ligne 22 indique ladd (pour plus longtemps)

Aussi, est-il sûr d'effectuer des opérations arithmétiques avec différentes primitives tant que vous assignez dans une variable de type primitif le plus dans votre expression?

Oui, et il est aussi « sûr » pour effectuer des opérations arithmétiques avec des tailles plus petites, en ce sens, ils ne cassent pas le programme, vous venez de perdre des informations.

Par exemple, essayez d'ajouter Integer.MAX_VALUE à Integer.MAX_VALUE pour voir ce qui se passe, ou int x = (int) (Long.MAX_VALUE - 1);

3

Aussi, est-il sûr d'effectuer l'arithmétique avec des primitives différentes, tant que vous assignez dans une variable de la plus large type primitif dans votre expression?

Cela dépend de ce que vous entendez par sécurité. Cela ne vous évitera certainement pas d'envisager la possibilité d'un débordement.

2
int a=5; 
long b=10; 
a+=b; 
System.out.println(a); 

La principale différence est que, avec a = a + b, il n'y a pas transtypage en cours, et si le compilateur se met en colère contre vous pour ne pas typecasting. Mais avec a += b, ce qu'il fait vraiment est typecasting b à a type compatible avec a.

+0

Donc, il fait un downcast invisible de «long» à ' int', potentiellement jeter des informations? Je suis tombé sur ceci dans 'java.io.ByteArrayInputStream # skip (long)' et j'ai fait une double prise. Je n'ai jamais vu ça avant. – nilskp

1

Cet exemple simple pourrait effacer les doutes sur la conversion de type de données dans le cas d'opérations arithmétiques dans Java.

byte a = 1; 
    short b = 1; 
    System.out.println(a+b);      //Output = 2 
    Object o = a+b;        //Object becomes int 
    System.out.println(o.getClass().getName()); //Output = java.lang.Integer 

    int c = 1; 
    System.out.println(a+b+c);     //Output = 3 
    o = a+b+c;         //Object becomes int 
    System.out.println(o.getClass().getName()); //Output = java.lang.Integer 

    long d = 1l; 
    System.out.println(a+b+c+d);     //Output = 4 
    o = a+b+c+d;         //Object becomes long 
    System.out.println(o.getClass().getName()); //Output = java.lang.Long 

    float e = 1.0f; 
    System.out.println(a+b+c+d+e);    //Output = 5.0 
    o = a+b+c+d+e;        //Object becomes float 
    System.out.println(o.getClass().getName()); //Output = java.lang.Float 

    double f = 1.0; 
    System.out.println(a+b+c+d+e+f);    //Output = 6.0 
    o = a+b+c+d+e+f;        //Object becomes double 
    System.out.println(o.getClass().getName()); //Output = java.lang.Double 

Voici l'ordre des types de données en fonction de gamme en Java:

byte<short<int<long<float<double 

C'est l'ordre dans lequel l'élargissement va se passer.

Note: le flotteur a plus de portée que de longueur, mais a une taille plus petite.