Pregunta División simple en Java: ¿se trata de un error o una característica?


Estoy intentando este simple cálculo en una aplicación Java:

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

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

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

Si hago:

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

Obtengo el resultado correcto que es b=0.3.

¿Qué está mal aquí?


16
2018-05-26 00:29


origen


Respuestas:


Estás usando la división de enteros.

Tratar 7.0/10 en lugar.


56
2018-05-26 00:30



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

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

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

24
2018-05-26 00:33



Por 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 de Fortran y Cobol.

Como ejemplo, la división entera de 10/3 arroja un valor entero 3 ya que un entero no tiene ninguna facilidad 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 bucle.

Digamos que deseamos imprimir un conjunto de 1000 cadenas, pero deseamos insertar un salto de línea después de cada 15ª 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 a 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();
  }
}

Variando k de una manera caprichosa en el bucle, podríamos imprimir una impresión triangular

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

Eso es para demostrar que, si consideras esto un error, esto "error"es una característica útil que no nos gustaría eliminar de ninguno de los varios idiomas que hemos utilizado hasta ahora.


8
2018-05-26 06:11



Encuentro que los identificadores de letras son más legibles y más indicativos del tipo analizado:

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

o:

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

1
2018-05-26 01:46



En mi caso, yo estaba haciendo esto:

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

En lugar de lo "correcto":

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

¡Presta atención con los paréntesis!


0
2018-01-12 11:01