Pregunta ¿Por qué Math.round devuelve un largo pero Math.floor devuelve un doble?


¿Por qué la inconsistencia?


32
2017-08-05 07:06


origen


Respuestas:


No hay inconsistencia: los métodos están simplemente diseñados para seguir diferentes especificaciones.

Entonces por diseño round redondea a un long y rint redondea a un double. Este ha sido siempre el caso desde JDK 1.0.

Se agregaron otros métodos en JDK 1.2 (p. toRadians, toDegrees); otros se agregaron en 1.5 (p. log10, ulp, signum, etc.) y, sin embargo, se agregaron algunos más en 1.6 (p. copySign, getExponent, nextUp, etc.) (busque el Ya que: metadatos en la documentación); pero round y rint siempre se han tenido el uno al otro como están ahora desde el principio.

Podría decirse que, tal vez en lugar de long round y double rint, sería más "consistente" nombrarlos double round y long rlong, pero esto es argumentativo. Dicho esto, si insistes en llamar categóricamente esto una "inconsistencia", entonces la razón puede ser tan insatisfactoria como "porque es inevitable".

Aquí hay una cita de Effective Java 2nd Edition, Item 40: Diseñe las firmas del método cuidadosamente:

En caso de duda, consulte las API de la biblioteca Java para obtener orientación. Si bien hay muchas inconsistencias, inevitables dado el tamaño y el alcance de estas bibliotecas, también existe una gran cantidad de consenso.

Preguntas a distancia


15
2017-08-05 07:57



floor habría sido elegido para que coincida con la rutina c estándar en math.h (rint, mencionado en otra respuesta, también está presente en esa biblioteca, y devuelve un double, como en java).

pero round no era una función estándar en c en ese momento (no se menciona en C89 - c identificadores y estándares; c99 define round y devuelve un doublecomo es de esperar). Es normal que los diseñadores de idiomas "tomen prestado" ideas, ¿entonces tal vez proviene de algún otro idioma? fortran 77 no tiene una función de ese nombre y no estoy seguro de qué otra cosa se hubiera utilizado en ese momento como referencia. quizás vb - eso tiene Round pero, desafortunadamente para esta teoría, devuelve un double (php también). curiosamente, perl deliberadamente evita definir ronda.

[actualización: hmmm. parece smalltalk devuelve enteros. no sé lo suficiente sobre smalltalk para saber si es correcto y / o general, y se llama el método rounded, pero podría ser la fuente. smalltalk sí influyó en Java de alguna manera (aunque más conceptualmente que en detalles).]

si no se trata de un lenguaje pequeño, entonces nos queda la hipótesis de que alguien simplemente eligió mal (dadas las conversiones implícitas posibles en java me parece que devolver un doublehubiera sido más útil, ya que puede usarse tanto al convertir tipos como al hacer cálculos de coma flotante).

en otras palabras: las funciones comunes a java yc tienden a ser consistentes con el estándar de biblioteca c en el momento; el resto parece ser arbitrario, pero esta particular arruga mayo han venido de smalltalk.


5
2018-03-17 04:18



Estoy de acuerdo, que es extraño que Math.round(double) devoluciones long. Si es grande double los valores se emiten a long (Que es que Math.round implícitamente lo hace), Long.MAX_VALUE es regresado. Una alternativa es usar Math.rint() para evitar eso Sin embargo, Math.rint() tiene un comportamiento de redondeo algo extraño: los enlaces se liquidan redondeando al entero par, es decir, 4.5 se redondea a 4.0, pero 5.5 se redondea a 6.0). Otra alternativa es usar Math.floor(x+0.5). Pero tenga en cuenta que 1.5 se redondea a 2, mientras que -1.5 se redondea a -1, no a -2. Otra alternativa más es usar Math.round, pero solo si el número está en el rango entre Long.MIN_VALUE y Long.MAX_VALUE. Los valores de punto flotante de doble precisión fuera de este rango son enteros de todos modos.

Desafortunadamente, por qué Math.round() devoluciones long es desconocido. Alguien tomó esa decisión, y probablemente nunca dio una entrevista para decirnos por qué. Supongo que Math.round fue diseñado para proporcionar una mejor forma (es decir, con redondeo) para convertir dobles en largos.


1
2018-03-17 02:49