Float e doppio tipo di dati in Java


Il tipo di dati float è una virgola mobile IEEE 754 a 32 bit a precisione singola e il tipo di dati double è una virgola mobile IEEE 754 a 64 bit a doppia precisione.

Cosa significa? E quando dovrei usare float invece di double o viceversa?

Author: Peter Mortensen, 2014-12-22

7 answers

La pagina di Wikipedia su di essa è un buon punto di partenza.

Per riassumere:

  • float è rappresentato in 32 bit, con 1 bit di segno, 8 bit di esponente e 23 bit del significato (o quanto segue da un numero di notazione scientifica: 2.33728*1012; 33728 è il significand).

  • double è rappresentato in 64 bit, con 1 bit di segno, 11 bit di esponente e 52 bit di significand.

Per impostazione predefinita, Java utilizza double per rappresentare i suoi numeri in virgola mobile (quindi un letterale 3.14 viene digitato double). È anche il tipo di dati che ti darà un intervallo di numeri molto più ampio, quindi incoraggerei fortemente il suo uso su float.

Potrebbero esserci alcune librerie che in realtà costringono l'utilizzo di float, ma in generale - a meno che tu non possa garantire che il risultato sarà abbastanza piccolo da adattarsi all'intervallo float prescritto , allora è meglio optare con double.

Se si richiede precisione - per ad esempio, non puoi avere un valore decimale impreciso (come 1/10 + 2/10), o stai facendo qualsiasi cosa con valuta (ad esempio, che rappresenta $10.33 nel sistema), quindi usa un BigDecimal, che può supportare una quantità arbitraria di precisione e gestire situazioni del genere con eleganza.

 212
Author: Makoto, 2017-02-24 22:19:04

Un galleggiante ti dà ca. 6-7 cifre decimali di precisione, mentre un doppio ti dà ca. 15-16. Anche la gamma di numeri è più grande per il doppio.

Un doppio ha bisogno di 8 byte di spazio di archiviazione mentre un float ha bisogno solo di 4 byte.

 65
Author: Henry, 2014-12-22 07:16:27

I numeri in virgola mobile, noti anche come numeri reali, vengono utilizzati quando si valutano espressioni che richiedono precisione frazionaria. Ad esempio, calcoli come radice quadrata o trascendentali come seno e coseno generano un valore la cui precisione richiede un tipo a virgola mobile. Java implementa lo standard (IEEE–754) set di floatingpoint tipi e operatori. Esistono due tipi di tipi a virgola mobile, float e double, che rappresentano numeri a precisione singola e doppia, rispettivamente. La loro larghezza e gli intervalli sono mostrati qui:


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


float

Il tipo float specifica un valore di precisione singola che utilizza 32 bit di archiviazione. La precisione singola è più veloce su alcuni processori e occupa la metà dello spazio della doppia precisione, ma diventerà imprecisa quando i valori sono molto grandi o molto piccoli. Le variabili di tipo float sono utili quando è necessario un componente frazionario, ma non richiedono un elevato grado di precisione. Ad esempio, float può essere utile quando rappresenta dollari e centesimi.

Ecco alcune dichiarazioni di variabili float di esempio:

Float hightemp, lowtemp;


doppio

Double precision, come indicato dalla parola chiave double, utilizza 64 bit per memorizzare un valore. La doppia precisione è in realtà più veloce della precisione singola su alcuni processori moderni che sono stati ottimizzati per calcoli matematici ad alta velocità. Tutte le funzioni matematiche trascendentali, come il peccato( ), cos () e sqrt () restituiscono valori doppi. Quando è necessario mantenere la precisione su molti calcoli iterativi o manipolare numeri di grande valore, double è la scelta migliore.

 12
Author: Ye Win, 2014-12-22 07:18:07

Java sembra avere un pregiudizio verso l'utilizzo di double per i calcoli comunque:

Caso in questione il programma che ho scritto prima di oggi, i metodi non hanno funzionato quando ho usato float, ma ora funzionano alla grande quando ho sostituito float con double (nell'IDE 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;
    }
}
 2
Author: Raymond Wachaga, 2017-11-15 19:28:16

Secondo gli standard IEEE, float è una rappresentazione a 32 bit di un numero reale mentre double è una rappresentazione a 64 bit.

Nei programmi Java normalmente vediamo principalmente l'uso del doppio tipo di dati. È solo per evitare overflow poiché l'intervallo di numeri che possono essere ospitati utilizzando il doppio tipo di dati è più che l'intervallo quando viene utilizzato float.

Anche quando è richiesta un'alta precisione, è incoraggiato l'uso del doppio. Pochi metodi di libreria che sono stati implementati molto tempo fa richiede ancora l'uso del tipo di dati float come must (solo perché è stato implementato usando float, nient'altro!).

Ma se sei sicuro che il tuo programma richiede numeri piccoli e un overflow non si verificherà con l'uso di float, allora l'uso di float migliorerà in gran parte la complessità dello spazio poiché i float richiedono metà della memoria come richiesto da double.

 1
Author: Rubal, 2017-11-15 19:25:34

Questo esempio illustra come estrarre il segno (il bit più a sinistra), l'esponente (gli 8 bit seguenti) e mantissa (i 23 bit più a destra) da un float in 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));

Lo stesso approccio può essere utilizzato per double (esponente a 11 bit e mantissa a 52 bit).

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));

Credito: http://s-j.github.io/java-float /

 0
Author: acohen, 2018-02-20 22:20:18

Questo darà errore:

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

/ MyClass.java: 3: errore: tipi incompatibili: possibile conversione con perdita da double a float float a = 0.5;

Questo funzionerà perfettamente bene

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

Questo funzionerà anche perfettamente bene

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

Motivo : Java per impostazione predefinita memorizza i numeri reali come doppi per garantire una maggiore precisione.

Double richiede più spazio ma più preciso durante il calcolo e float richiede meno spazio ma meno preciso.

 0
Author: Himanshu Singh, 2018-07-29 13:34:08