Float i double datatype w Javie

Typ danych zmiennoprzecinkowych jest 32-bitowym zmiennoprzecinkowym IEEE 754 o pojedynczej precyzji, a typ danych double jest 64-bitowym zmiennoprzecinkowym IEEE 754 o podwójnej precyzji.

Co to znaczy? A kiedy powinienem używać float zamiast double lub vice-versa?

Author: Peter Mortensen, 2014-12-22

7 answers

Strona Wikipedia na niej jest dobrym miejscem do rozpoczęcia.

Podsumowując:

  • float jest reprezentowana w 32 bitach, z 1 bitem znaku, 8 bitami wykładnika i 23 bitami significand (lub co wynika z liczby naukowej notacji: 2.33728*1012; 33728 is the significand).

  • double jest reprezentowany w 64 bitach, z 1 bitem znaku, 11 bitami wykładnika i 52 bitami significand.

Domyślnie Java używa double do reprezentowania jej liczb zmiennoprzecinkowych (tak więc literał {[3] } jest wpisany double). Jest to również typ danych, który da znacznie większy zakres liczb, więc gorąco zachęcam do jego użycia nad float.

Mogą istnieć pewne biblioteki, które faktycznie wymuszają użycie float, ale ogólnie - chyba że możesz zagwarantować, że Twój wynik będzie wystarczająco mały, aby zmieścić się w zalecanym zakresie float , najlepiej wybrać double.

Jeśli potrzebujesz dokładności-dla na przykład, nie możesz mieć wartości dziesiętnej, która jest niedokładna (jak 1/10 + 2/10), lub robisz cokolwiek Z walutą (na przykład reprezentującą $10.33 w systemie), a następnie użyj BigDecimal, która może obsługiwać dowolną ilość precyzji i obsługiwać takie sytuacje elegancko.

 212
Author: Makoto,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-02-24 22:19:04

Pływak daje ok. Precyzja 6-7 cyfr dziesiętnych, podczas gdy podwójne daje ok. 15-16. Również zakres liczb jest większy dla podwójnego.

Double potrzebuje 8 bajtów przestrzeni dyskowej, podczas gdy float potrzebuje tylko 4 bajtów.

 65
Author: Henry,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-12-22 07:16:27

Liczby zmiennoprzecinkowe, znane również jako liczby rzeczywiste, są używane do oceny wyrażeń wymagających precyzji ułamkowej. Na przykład obliczenia takie jak pierwiastek kwadratowy lub wartości transcendentalne, takie jak sinus i cosinus, dają wartość, której precyzja wymaga typu zmiennoprzecinkowego. Java implementuje standardowy (IEEE–754) zestaw typów i operatorów floatingpoint. Istnieją dwa rodzaje typów zmiennoprzecinkowych, float i double, które reprezentują liczby pojedynczej i podwójnej precyzji, odpowiednio. Ich szerokość i zakresy są pokazane tutaj:


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


float

Typ float określa wartość o pojedynczej precyzji, która wykorzystuje 32 bity pamięci. Pojedyncza precyzja jest szybsza w niektórych procesorach i zajmuje o połowę mniej miejsca niż Podwójna precyzja, ale staje się nieprecyzyjna, gdy wartości są albo bardzo duże, albo bardzo małe. Zmienne typu float są przydatne, gdy potrzebny jest składnik ułamkowy, ale nie wymagają dużego stopnia precyzji. Na przykład float może być przydatny przy reprezentowaniu dolarów i centów.

Oto przykładowe deklaracje zmiennych float:

Float hightemp, lowtemp;


double

Podwójna precyzja, oznaczona słowem kluczowym double, używa 64 bitów do przechowywania wartości. Podwójna precyzja jest w rzeczywistości szybsza niż pojedyncza precyzja w niektórych nowoczesnych procesorach, które zostały zoptymalizowane pod kątem szybkich obliczeń matematycznych. Wszystkie transcendentalne funkcje matematyczne, takie jak sin( ), cos () I sqrt () zwracają podwójne wartości. Kiedy musisz zachować dokładność wielu obliczeń iteracyjnych lub manipulować liczbami o dużej wartości, double jest najlepszym wyborem.

 12
Author: Ye Win,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-12-22 07:18:07

Wydaje się, że Java ma stronniczość w stosunku do używania podwójnego do obliczeń:

PrzykĹ 'adowo program, ktĂłry napisaĹ' em wczeĹ "niej, metody nie dziaĹ' ajÄ..., gdy uĺźywaĺ 'em float, ale teraz dziaĹ' ajÄ ... wspaniale, gdy podmieniĺ ' em float na double (w NetBeans IDE):

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,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-15 19:28:16

Zgodnie ze standardami IEEE, float jest 32-bitową reprezentacją liczby rzeczywistej, podczas gdy double jest 64-bitową reprezentacją.

W programach Java zwykle widzimy użycie typu danych double. Chodzi o to, aby uniknąć przepełnień, ponieważ zakres liczb, które można uwzględnić przy użyciu typu danych double, jest większy niż zakres, gdy jest używany float.

Również wtedy, gdy wymagana jest wysoka precyzja, zaleca się stosowanie podwójnego. Kilka metod bibliotecznych zaimplementowanych dawno temu nadal wymaga użycia typu danych float jako koniecznoĹ "ci (to tylko dlatego, Ĺźe zostaĹ' o zaimplementowane przy uĹźyciu float, nic wiÄ ™ cej!).

Ale jeśli jesteś pewien, że twój program wymaga małych liczb, a przepełnienie nie wystąpi przy użyciu float, to użycie float znacznie poprawi Twoją złożoność przestrzeni, ponieważ pływaki wymagają dwukrotnie połowy pamięci.

 1
Author: Rubal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-15 19:25:34

Ten przykład ilustruje jak wydobyć znak (lewy bit), exponent (8 kolejnych bitów) i mantissa (23 prawe bity) z float w Javie.

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

To samo podejście może być używane dla double ' s (wykładnik 11-bitowy i mantysa 52-bitowa).

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

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

 0
Author: acohen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-20 22:20:18

To spowoduje błąd:

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

/MyClass.java: 3: error: incompatible types: possible lossy conversion from double to float float a = 0.5;

To będzie działać doskonale

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

To również będzie działać doskonale

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

Reason: Java domyślnie przechowuje liczby rzeczywiste jako podwójne, aby zapewnić większą precyzję.

Double zajmuje więcej miejsca, ale jest bardziej precyzyjny podczas obliczeń, a float zajmuje mniej miejsca, ale mniej precyzyjny.

 0
Author: Himanshu Singh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-29 13:34:08