2011-07-20 18 views
7
class LongDiv{ 
public static void main(String [] args){ 

    final long x = 24*60*60*1000*1000; 
    final long y = 24*60*60*1000; 
    System.out.println(x/y); 
} 
} 

aunque la respuesta esperada es 1000, pero el javac lo da como 5. ¿Motivo?Long Division en Java no funciona como se esperaba

+1

http://ideone.com/z78Sg –

+0

http: // Ideone.com/3vygF –

Respuesta

13

La larga x que está creando no es el valor que se esperaba. Está en el rango entero. Para crear largos, utilice:

final long x = 24L*60L*60L*1000L*1000L; 
final long y = 24L*60L*60L*1000L; 
System.out.println(x/y); 

El x se computada, en el rango de números enteros, era 500654080. Esto se divide por y (= 86400000), resulta en 5.794607407407407.... Java trunca la parte decimal que hace que el

5.

Mediante la adición de un L después de que el número literal, se indica al compilador para compilar como un long en lugar de un int. El valor para x que esperaba es 86400000000. Pero fue compilado como un int.

podemos reproducir el valor incorrecto para x (500654080) truncándolo a un int:

// First correct 
long x = 24L*60L*60L*1000L*1000L; 
/* x = `86400000000`; */ 
// Now truncate 
x &= 0xFFFFFFFFL; // again: don't forget the L suffix 
/* x = `500654080` */ 
+3

Solo uno de esos literales en cada expresión debe ser un 'largo'. Ver la respuesta de @Peter. –

+0

@Martijn: aceptado. pero ¿cómo es la respuesta 5? –

+0

Lo sé, pero creo que esta es una preferencia de estilo. –

5

Las expresiones 24*60*60*1000*1000 es un tipo int no es un long Lo que queremos es que es 24L*60*60*1000*1000long

Esto es lo que tienes.

final long x = (24*60*60*1000*1000) & 0xFFFFFFFF; 
final long y = (24*60*60*1000) & 0xFFFFFFFF; 
System.out.println(x/y); 

lo que quiere es

final long x = 24L*60*60*1000*1000; 
final long y = 24L*60*60*1000; 
System.out.println(x/y); 
+0

Para ser explícito al respecto, siempre puedes hacer un '1L * 24 * 60 * 60 * 1000 * 1000'. –

+0

En ese caso, podría hacer '(largo) 24 * 60 * 60 * 1000 * 1000 ' –

+0

¿Cuándo ocurriría la promoción int-> larga? ¿Para 24 o el resultado completo (intificado)? –

1

24*60*60*1000*1000 es demasiado grande para caber en un int y desbordamientos.

1

¡Tricky one!

El problema es que 24, 60 y 1000 son Java literal ints. Antes de asignar los valores a xey, se truncan para ajustarse a los valores int. Pruebe

System.out.print(x + ", " + y); 

para ver exactamente lo que quiero decir. La solución rápida es hacer que sus literales en valores largos de este modo:

public class LongDiv{ 
public static void main(String [] args){ 

    final long x = 24l*60l*60l*1000l*1000l; 
    final long y = 24l*60l*60l*1000l; 
    System.out.println(x/y); 
} 
} 
+0

¡Golpeado al golpe! No es tan complicado como pensaba, supongo :) – Eric

2

fundición (forzar) a las obras largas en el caso de los valores literales para el operando derecho; pero el problema persiste en el caso de la asignación de una variable de largo a otro, como en el ejemplo que se da a continuación:

package utils; 

public class Utils { 

    public static void main(String ... clps){ 
     Utils.longDivision(); 
     Utils.doubleDivision(); 
    } 

    private static void doubleDivision(){ 
     double x=new Long("54321").doubleValue(); 
     double y=new Long("12345").doubleValue(); 
     double difference=x - y; 
     double percentage=(difference/x)*100.00; 
     System.out.println("\nDouble Division ==> X : "+x+" ; Y : "+y+" ; Difference : "+difference+" ; percentage : "+percentage+"\n"); 
    } 

    private static void longDivision(){ 
     long x=new Long("54321").longValue(); 
     long y=new Long("12345").longValue(); 
     long difference=x - y; 
     long percentage=(difference/x)*100L; 
     System.out.println("\nLong Division ==> X : "+x+" ; Y : "+y+" ; Difference : "+difference+" ; percentage : "+percentage+"\n"); 
    } 

} 

La única manera de conseguir la respuesta adecuada es mediante la conversión de la división de productos largos en la división de dobles. Es muy extraño por qué la división de longs se comporta de una manera tan misteriosa.

longDivision da la respuesta como cero mientras que doubleDivision da la respuesta correcta.

espero que esto ayude a otras personas que se encontraron con problemas similares ...

Cuestiones relacionadas