Flotante y doble tipo de datos en Java

El tipo de datos flotantes es un punto flotante IEEE 754 de precisión simple de 32 bits y el tipo de datos dobles es un punto flotante IEEE 754 de 64 bits de doble precisión.

Qué significa eso? ¿Y cuándo debería usar float en lugar de double o viceversa?

La página de Wikipedia es un buen lugar para comenzar.

Para resumir:

  • float se representa en 32 bits, con 1 bit de signo, 8 bits de exponente y 23 bits del significado (o lo que sigue de un número de notación científica: 2.33728 * 10 12 ; 33728 es el significado).

  • double está representado en 64 bits, con 1 bit de signo, 11 bits de exponente y 52 bits de significado.

De forma predeterminada, Java usa el double para representar sus números de coma flotante (por lo que un literal 3.14 se escribe en double ). También es el tipo de datos que le dará un rango de números mucho más grande, por lo que recomendaría su uso sobre float .

Puede haber ciertas bibliotecas que realmente fuercen el uso del float , pero en general, a menos que pueda garantizar que su resultado sea lo suficientemente pequeño como para caber en el rango prescrito de float , entonces es mejor optar por el double .

Si necesita precisión, por ejemplo, no puede tener un valor decimal que sea impreciso (como 1/10 + 2/10 ) o que esté haciendo algo con la moneda (por ejemplo, que represente $ 10.33 en el sistema), luego utilice un BigDecimal , que puede admitir una cantidad arbitraria de precisión y manejar situaciones como esa elegantemente.

Un flotador te da aprox. 6-7 dígitos decimales de precisión mientras que un doble te da aprox. 15-16. También el rango de números es más grande para el doble.

Un doble necesita 8 bytes de espacio de almacenamiento, mientras que un flotador solo necesita 4 bytes.

Los números de coma flotante, también conocidos como números reales, se utilizan al evaluar expresiones que requieren precisión fraccionaria. Por ejemplo, cálculos como raíz cuadrada o transcendentales como seno y coseno dan como resultado un valor cuya precisión requiere un tipo de coma flotante. Java implementa el conjunto estándar (IEEE-754) de tipos y operadores de punto flotante. Hay dos tipos de tipos de coma flotante, flotante y doble, que representan números de precisión simple y doble, respectivamente. Su ancho y rangos se muestran aquí:

  Name Width in Bits Range double 64 1 .7e–308 to 1.7e+308 float 32 3 .4e–038 to 3.4e+038 

flotador

El tipo float especifica un valor de precisión simple que usa 32 bits de almacenamiento. La precisión simple es más rápida en algunos procesadores y ocupa la mitad de espacio que la doble precisión, pero se volverá imprecisa cuando los valores sean muy grandes o muy pequeños. Las variables de tipo flotante son útiles cuando se necesita un componente fraccionario, pero no requieren un alto grado de precisión. Por ejemplo, flotar puede ser útil cuando se representan dólares y centavos.

Aquí hay algunos ejemplos de declaraciones de variables flotantes:

flotar a alta temperatura, lowtemp;

doble

La precisión doble, como se indica mediante la palabra clave doble, usa 64 bits para almacenar un valor. La precisión doble es realmente más rápida que la precisión simple en algunos procesadores modernos que se han optimizado para cálculos matemáticos de alta velocidad. Todas las funciones matemáticas trascendentales, como sin (), cos () y sqrt (), devuelven valores dobles. Cuando necesite mantener la precisión sobre muchos cálculos iterativos, o esté manipulando números de gran valor, el doble es la mejor opción.

Sin embargo, Java parece tener un sesgo hacia el uso del doble para los cálculos:

Ejemplo del progtwig que escribí el día de hoy, los métodos no funcionaron cuando utilicé float, pero ahora funcionan muy bien cuando sustituí float por double (en el IDE de NetBeans):

 package palettedos; import java.util.*; class Palettedos{ private static Scanner Z = new Scanner(System.in); public static final double pi = 3.142; public static void main(String[]args){ Palettedos A = new Palettedos(); System.out.println("Enter the base and height of the triangle respectively"); int base = Z.nextInt(); int height = Z.nextInt(); System.out.println("Enter the radius of the circle"); int radius = Z.nextInt(); System.out.println("Enter the length of the square"); long length = Z.nextInt(); double tArea = A.calculateArea(base, height); double cArea = A.calculateArea(radius); long sqArea = A.calculateArea(length); System.out.println("The area of the triangle is\t" + tArea); System.out.println("The area of the circle is\t" + cArea); System.out.println("The area of the square is\t" + sqArea); } double calculateArea(int base, int height){ double triArea = 0.5*base*height; return triArea; } double calculateArea(int radius){ double circArea = pi*radius*radius; return circArea; } long calculateArea(long length){ long squaArea = length*length; return squaArea; } } 

De acuerdo con los estándares IEEE, float es una representación de 32 bits de un número real, mientras que double es una representación de 64 bits.

En los progtwigs de Java, normalmente vemos el uso del tipo de datos doble. Es solo para evitar desbordamientos, ya que el rango de números que se pueden acomodar usando el tipo de datos doble es más que el rango cuando se usa flotante.

También cuando se requiere alta precisión, se recomienda el uso del doble. Pocos métodos de la biblioteca que se implementaron hace mucho tiempo todavía requieren el uso del tipo de datos float como una obligación (eso es solo porque se implementó usando float, ¡nada más!).

Pero si está seguro de que su progtwig requiere un número pequeño y no se producirá un desbordamiento con el uso del flotador, entonces el uso del flotador mejorará en gran medida la complejidad de su espacio ya que los flotadores requieren la mitad de la memoria como se requiere en el doble.

Este ejemplo ilustra cómo extraer el signo (el bit más a la izquierda), el exponente (los 8 bits siguientes) y mantissa (los 23 bits más a la derecha) de un flotante en Java.

 int bits = Float.floatToIntBits(-0.005f); int sign = bits >>> 31; int exp = (bits >>> 23 & ((1 << 8) - 1)) - ((1 << 7) - 1); int mantissa = bits & ((1 << 23) - 1); System.out.println(sign + " " + exp + " " + mantissa + " " + Float.intBitsToFloat((sign << 31) | (exp + ((1 << 7) - 1)) << 23 | mantissa)); 

El mismo enfoque se puede usar para dobles (exponente de 11 bits y mantisa de 52 bits).

 long bits = Double.doubleToLongBits(-0.005); long sign = bits >>> 63; long exp = (bits >>> 52 & ((1 << 11) - 1)) - ((1 << 10) - 1); long mantissa = bits & ((1L << 52) - 1); System.out.println(sign + " " + exp + " " + mantissa + " " + Double.longBitsToDouble((sign << 63) | (exp + ((1 << 10) - 1)) << 52 | mantissa)); 

Crédito: http://sj.github.io/java-float/

Esto dará un error:

 public class MyClass { public static void main(String args[]) { float a = 0.5; } } 

/MyClass.java:3: error: tipos incompatibles: posible conversión con pérdida del doble al flotante flotante a = 0.5;

Esto funcionará perfectamente bien

 public class MyClass { public static void main(String args[]) { double a = 0.5; } } 

Esto también funcionará perfectamente bien

 public class MyClass { public static void main(String args[]) { float a = (float)0.5; } } 

Motivo : Java por defecto almacena números reales como dobles para garantizar una mayor precisión.

El doble requiere más espacio pero es más preciso durante el cálculo y el flotador ocupa menos espacio pero es menos preciso.