2010-05-26 7 views
15

estoy tratando este cálculo simple en una aplicación Java:División simple en Java: ¿se trata de un error o una característica?

System.out.println("b=" + (1 - 7/10)); 

Obviamente quiero b=0.3 para la salida, pero esto es lo que me sale b=1.

¿Qué ?! ¿Por qué sucede esto?

si hago:

System.out.println("b=" + (1 - 0.7)); 

puedo obtener el resultado correcto que es b=0.3.

¿Qué está mal aquí?

Respuesta

54

Está utilizando la división de enteros.

Pruebe 7.0/10 en su lugar.

+23

Añadiré que esto no es un error. Es una característica. ':]' –

+8

ni error ni característica: está "funcionando como se diseñó". –

+1

Si está trabajando con variables, puede simplemente lanzar cualquiera de ellas para flotar. a = 1; b = 2; a/b = 0; (float) a/b = 0.5; a/(float) b = 0.5; – Azee

24

Has usado enteros en la expresión 7/10, y el número entero 7 dividido por el entero 10 es cero.

Lo que estás esperando es la división en coma flotante. Cualquiera de los siguientes sería evaluar la forma esperada:

7.0/10 
7/10.0 
7.0/10.0 
7/(double) 10 
1

me parece identificadores de letras para ser más legible y más indicativa del tipo de procesado:

1 - 7f/10 
1 - 7/10f 

o:

1 - 7d/10 
1 - 7/10d 
8

favor no tome esto como una respuesta a la pregunta. No lo es, sino un consejo relacionado con la explotación de la diferencia de int y float. Hubiera puesto esto bajo un comentario, excepto que el cuadro de respuesta me permite formatear este comentario.

Esta característica se ha utilizado en todos los lenguajes de programación respetables desde los días de fortran (o antes) - Debo confesar que una vez fui programador de tarjetas perforadas Fortran y Cobol.

Como ejemplo, la división entera de 10/3 arroja un valor entero 3 ya que un entero no tiene ninguna capacidad para mantener el residual fraccionario .3333 ...

Una de las formas en que nosotros (los antiguos programadores antiguos) hemos estado usando esta función es el control de ciclo.

Digamos que deseamos imprimir un conjunto de 1000 cadenas, pero deseamos insertar un salto de línea después de cada 15a secuencia, para insertar algunos caracteres agradables al final de la línea y al comienzo de la siguiente línea. Explotamos esto, dado que el entero k es la posición de una cadena en esa matriz.

int(k/15)*15 == k 

es verdadero solo cuando k es divisible por 15, una ocurrencia con una frecuencia de cada 15 celdas. Lo cual es similar a lo que dijo mi amigo acerca de que el reloj muerto de su abuelo era exacto dos veces al día.

int(1/15) = 0 -> int(1/15)*15 = 0 
int(2/15) = 0 -> int(2/15)*15 = 0 
... 
int(14/15) = 0 -> int(14/15)*15 = 0 
int(15/15) = 1 -> int(15/15)*15 = 15 

int(16/15) = 1 -> int(16/15)*15 = 15 
int(17/15) = 1 -> int(17/15)*15 = 15 
... 
int(29/15) = 1 -> int(29/15)*15 = 15 
int(30/15) = 2 -> int(30/15)*15 = 30 

Por lo tanto, el bucle,

leftPrettyfy(); 
for(int k=0; k<sa.length; k++){ 
    print(sa[k]); 
    int z = k + 1; 
    if ((z/15)*15 == z){ 
    rightPrettyfy(); 
    leftPrettyfy(); 
    } 
} 

Mediante la variación de k de una manera caprichosa en el bucle, se podría imprimir una copia impresa triangular

1 
2 3 
4 5 6 
7 8 9 10 
11 12 13 14 15 

Eso es demostrar que, si Considera que esto es un error, este "error " es una función útil que no nos gustaría que se elimine de ninguno de los varios idiomas que hemos utilizado hasta ahora.

+5

¿Hay algún problema con 'k% 15 == 0'? – Corey

+0

Como mod (a, x) = a - (x * int (a/x)), creo que la respuesta reside en que además de la carga de construir un argumento repetidamente más un código jmp para llamar a una subrutina módulo, puedes contar que el en línea a == (x * int (a/x)) es una operación más eficiente que a - (x * int (a/x)) == 0. –

+0

Escribí "Variando k en una fantasía forma en el ciclo, podríamos imprimir una impresión triangular ", para k == (k/L) * L. Debería haber sido: "Al variar L de una manera fantástica en el ciclo, podríamos imprimir una impresión triangular". –

0

En mi caso yo estaba haciendo esto:

double a = (double) (MAX_BANDWIDTH_SHARED_MB/(qCount+1)); 

En lugar de la "correcta":

double a = (double)MAX_BANDWIDTH_SHARED_MB/(qCount+1); 

desviar la atención con los paréntesis!

Cuestiones relacionadas