1. Redondeo de números reales
Como ya hemos discutido, cuando se asigna un número real a una intvariable, siempre se redondea hacia abajo al entero menor más cercano: la parte fraccionaria simplemente se descarta.
Pero es fácil imaginar una situación en la que un número fraccionario deba redondearse al entero más cercano en cualquier dirección o incluso redondearse hacia arriba. ¿Qué haces en este caso?
Para esto y para muchas situaciones similares, Java tiene la Mathclase, que tiene los métodos round(), ceil()y floor().
Math.round()método
El Math.round()método redondea un número al entero más cercano:
long x = Math.round(real_number)
Pero aquí hay otro matiz: este método devuelve un longnúmero entero (no un int). Debido a que los números reales pueden ser muy grandes, los creadores de Java decidieron utilizar el tipo de entero más grande disponible en Java: long.
En consecuencia, si un programador quiere asignar el resultado a una intvariable, debe indicar explícitamente al compilador que acepta la posible pérdida de datos (en el caso de que el número resultante no encaje en un inttipo).
int x = (int) Math.round(real_number)
Ejemplos:
| Declaración | Resultado |
|---|---|
|
|
|
|
|
|
Math.ceil()método
El Math.ceil()método redondea un número a un entero. Aquí hay ejemplos:
| Declaración | Resultado |
|---|---|
|
|
|
|
|
|
Math.floor()método
El Math.floor()método redondea un número a un entero. Aquí hay ejemplos:
| Declaración | Resultado |
|---|---|
|
|
|
|
|
|
Por supuesto, al redondear un número a un número entero, es más fácil simplemente usar un operador de conversión de tipos:(int)
| Declaración | Resultado |
|---|---|
|
|
Si le resulta difícil recordar estos nombres, una breve lección de inglés le ayudará:
Mathsignifica matemáticasRoundsignifica redondoCeilingsignifica techoFloorsignifica piso
2. Cómo se estructuran los números de punto flotante
El doubletipo puede almacenar valores en el rango de a . Este amplio rango de valores (en comparación con el tipo) se explica por el hecho de que el tipo (así como ) tiene una estructura interna completamente diferente a los tipos enteros. Internamente, el tipo codifica su valor como dos números: el primero se llama mantisa y el segundo se llama exponente .-1.7*10308+1.7*10308intdoublefloatdouble
Digamos que tenemos el número 123456789y lo almacenamos como una doublevariable. Cuando lo hacemos, el número se convierte en , e internamente el tipo almacena dos números: y . La mantisa ("parte significativa del número" o mantisa) se resalta en rojo, mientras que el exponente se resalta en azul.1.23456789*108double234567898
Este enfoque hace posible almacenar tanto números muy grandes como muy pequeños. Pero debido a que la representación del número está limitada a 8 bytes (64 bits) y algunos de los bits se usan para almacenar el exponente (así como el signo de la mantisa y el signo del exponente), el máximo de dígitos disponibles para representar la mantisa es 15 _
Esta es una descripción muy simplificada de cómo se estructuran los números reales.
3. Pérdida de precisión al trabajar con números reales
Cuando trabaje con números reales, siempre tenga en cuenta que los números reales no son exactos . Siempre puede haber errores de redondeo y errores de conversión al convertir de decimal a binario. Además, la fuente de error más común es la pérdida de precisión al sumar o restar números en escalas radicalmente diferentes.
Este último hecho es un poco alucinante para los programadores novatos.
Si restamos de , obtenemos .1/109109109
| Restar números en escalas radicalmente diferentes | Explicación |
|---|---|
|
El segundo número es extremadamente pequeño , lo que hará que su significado (resaltado en gris) sea ignorado. Los 15 dígitos significativos están resaltados en naranja. |
Qué podemos decir, programación no es lo mismo que matemáticas.
4. Trampa al comparar números reales
Otro peligro acecha a los programadores cuando comparan números reales. Surge cuando se trabaja con números reales, porque se pueden acumular errores de redondeo. El resultado es que hay situaciones en las que se espera que los números reales sean iguales, pero no lo son. O viceversa: se espera que los números sean diferentes, pero son iguales.
Ejemplo:
| Declaración | Explicación |
|---|---|
|
El valor de la variable a será 1000000000.0El valor de la variable c será 1000000000.0(el número en la b variable es demasiado pequeño) |
En el ejemplo anterior, ay cno deberían ser iguales, pero lo son.
O pongamos otro ejemplo:
| Declaración | Explicación |
|---|---|
|
El valor de la variable a será 1.0El valor de la variable b será1.0 |
5. Un dato interesante sobrestrictfp
Java tiene una palabra clave especial (puntostrictfp flotante estricto ) , que no se encuentra en otros lenguajes de programación . ¿Y sabes por qué lo necesitas? Empeora la precisión de las operaciones con números de coma flotante. Aquí está la historia de cómo llegó a ser:
GO TO FULL VERSION