Плаваючий та подвійний тип даних на Java


220

Тип даних поплавця - це одноточна 32-бітна плаваюча точка IEEE 754, а подвійний тип даних - це 64-розрядна плаваюча точка IEEE 754 з подвоєною точністю.

Що це означає? І коли я повинен використовувати float замість подвійного чи навпаки?


8
Ви повинні використовувати плавці замість подвійних, коли використання пам'яті є критичним. Якщо вам потрібні більш точні обчислення, використовуйте парні.
Everv0id

12
@ Everv0id: Я не впевнений у будь-якій ситуації, в якій пам'ять була настільки тісною, що треба було пожертвувати точністю для простору. (Ти використовуєш Java , заради богу ...) Можуть виникнути ситуації, коли це вимагається, але в моїй практиці я це бачив дуже рідко. Якщо ви хотіли детальніше пояснити, чому ви вважаєте, що це гарна ідея, надання відповіді за допомогою прикладу було б гідним доповненням.
Макото


5
@Makoto насправді, я ніколи не використовував поплавці, а лише парні. Але можуть бути додатки (теоретично), які повинні зберігати велику кількість чисел з плаваючою комою, тому використання 2x пам'яті може бути критичним. Теоретично, ofc; на практиці ви завжди можете придбати ще один сервер .
Everv0id

3
Я використовував 4-байтні і навіть 2-байтні фіксовані точні числа, щоб зберегти пам’ять, але якщо у вас мільярди таких, навряд чи варто. Час, який вам знадобиться написати "подвійний" замість "плавати" (він має ще одну букву), коштує в 1000 разів більше, ніж додаткова пам'ять, яку ви використовуєте, але якщо використання, doubleа не floatвбереже вас від помилки, пов'язаної з точністю, воно того варте .
Пітер Лорі

Відповіді:


259

Сторінка Вікіпедії на ньому - гарне місце для початку.

Підсумовуючи:

  • floatпредставлений у 32 бітах, з 1 бітовим знаком, 8 бітами показника та 23 бітами ознаки (або що випливає з науково-нотаційного номера: 2.33728 * 10 12 ; 33728 - значення).

  • double представлений у 64 бітах, з 1 знаком біта, 11 бітів експонента та 52 бітом ознакиі.

За замовчуванням Java використовує doubleдля представлення своїх цифр з плаваючою комою (тому 3.14вводиться літерал double). Це також тип даних, який дасть вам значно більший діапазон чисел, тому я б настійно заохочував його використання float.

Там можуть бути деякі бібліотеки , які на насправді змусити ваше використання float, але в цілому - якщо ви не можете гарантувати , що ваш результат буде досить малий , щоб поміститися в float«s запропонованого діапазону , то це краще зробити вибір з double.

Якщо вам потрібна точність - наприклад, ви не можете мати неточне значення десяткової (наприклад 1/10 + 2/10), або ви робите що- небудь з валютою (наприклад, що становить 10,33 дол. США в системі), тоді використовуйте знак BigDecimal, який може підтримувати довільна кількість точності та вирішення подібних ситуацій.


4
Чи не 233728 == мантіса в наведеному прикладі? Я маю на увазі, де ще зберігається ціла частина?
JaLoveAst1k

1
@ mathguy54: У наукових позначеннях 2 було б цілим цілим, а .33728 - мантісою. Ось посилання на це.
Макото

5
Я шукав інформацію про поплавці та дублі, і знайшов це, і мені потрібно було прокоментувати: якщо ви робите щось із валютою, яка не включає дробові центи, використання BigDecimal є смішним. Загальна валюта - це дискретні дані, тому вам слід використовувати цілий тип даних. (Це одна з найпоширеніших помилок молодих програмістів - оскільки ми використовуємо А. для розділення доларів від центів, вони думають, що це значення з плаваючою комою. Це не так.)
Trixie Wolf

2
@TrixieWolf, чи можете ви бути більш конкретними, чи пропонували ви використовувати два цілі числа (цілу і десяткову частини)? А ви говорите про загальну валюту, а про решту? Деяка сума оцінюється в 6 десяткових знаків, тому ви не можете просто *100. Будь ласка, у вас тут є точка, але чи можете ви бути точнішими :)
AxelH

9
@AxelH За винятком серед фінансових розрахунків, де можуть існувати дробові центи, гроші завжди дискретні. Ви б використовували один цілий тип для зберігання даних. Таким чином, 5,34 дол. США зберігається як 534. Частка долара становить вал / 100 в цілочисловій математиці, а центи - вал% 100 у цілій математиці, де% посилається на решту операцій. Для грошей, де більше десятків місць після десяткових, його все одно слід зберігати як цілісне, оскільки він дискретний. Навіть якщо це не дискретно, часто вам потрібно буде відмовитися від дискретного сховища більшу частину часу, оскільки це точно, тому ви не втратите гроші на помилки округлення.
Trixie Wolf

72

Поплавок дає ок. 6-7 десяткових цифр точності, а подвійний дає прибл. 15-16. Також діапазон чисел більший для подвійних.

Для подвійного простору потрібно 8 байтів, а флоату потрібно лише 4 байти.


13

Числа з плаваючою комою, також відомі як реальні числа, використовуються при оцінці виразів, які потребують дробової точності. Наприклад, такі обчислення, як квадратний корінь або трансцендентали, такі як синус і косинус, призводять до значення, точність якого вимагає типу з плаваючою комою. Java реалізує стандартний (IEEE-754) набір типів і операторів з плаваючою точкою. Існує два види типу з плаваючою комою, плаваючі та подвійні, які представляють числа одно- та подвійної точності відповідно. Їх ширина та діапазони показані тут:


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


плавати

Поплавок типу задає значення одноточності, яке використовує 32 біти зберігання. Одноточна точність на деяких процесорах швидша і займає вдвічі більше місця, ніж подвійна точність, але стане неточною, коли значення або дуже великі, або дуже малі. Змінні типу float корисні, коли вам потрібен дробовий компонент, але не потребують великої точності.

Ось кілька прикладів декларування змінної змінної:

float hightemp, lowtemp;


подвійний

Подвійна точність, позначена подвійним ключовим словом, використовує 64 біт для зберігання значення. Подвійна точність насправді швидша, ніж одна точність на деяких сучасних процесорах, оптимізованих для високошвидкісних математичних обчислень. Усі трансцендентальні математичні функції, такі як sin (), cos () та sqrt (), повертають подвійні значення. Коли вам потрібно підтримувати точність над багатьма ітераційними розрахунками або маніпулюєте великими числами, найкращим вибором є подвійний.


Ця відповідь для чітко уточненого, коли нам слід використовувати float та double.hhy ні?
Ви виграєте

8
Ні я, floatні doubleтипи найкраще не використовуються для валюти на Java, оскільки вони відкривають можливість помилок округлення. Ця стаття описується детальніше: javapractices.com/topic/TopicAction.do?Id=13
PPartisan

1
"float може бути корисним при представленні доларів та центів." - ні, ні, ні, nononono. Ніколи, ніколи не зберігайте валюту як плаваючі / подвійні.
зменшення активності

2

Здається, у Java є ухил до використання подвійних для обчислень:

У конкретному випадку програмою, про яку я писав раніше, методи не працювали, коли я використовував float, але зараз чудово працює, коли я замінив float подвійним (у ID 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

Це призведе до помилки:

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

/MyClass.java:3: помилка: несумісні типи: можлива конверсія втрат з подвійного в плаваючий float a = 0,5;

Це буде прекрасно працювати

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

Це також буде прекрасно працювати

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

Причина : Java за замовчуванням зберігає реальні числа як подвійні, щоб забезпечити більш високу точність.

Double займає більше місця, але більш точний під час обчислень, а float займає менше місця, але менш точний.


1

Відповідно до стандартів IEEE, float - це 32-бітове представлення реального числа, а double - 64-бітове представлення.

У програмах Java ми зазвичай бачимо використання подвійного типу даних. Просто уникнути переповнення, оскільки діапазон чисел, який можна розмістити за допомогою подвійного типу даних, більше, ніж діапазон, коли використовується флоат.

Також, коли потрібна висока точність, рекомендується використання подвійної. Мало бібліотечних методів, що були впроваджені давно, все ще вимагає використання типу даних float як обов'язкового (це лише тому, що він був реалізований за допомогою float, нічого іншого!).

Але якщо ви впевнені, що вашій програмі потрібна невелика кількість і переповнення не буде відбуватися при використанні float, то використання float значно покращить вашу космічну складність, оскільки плавці потребують половини пам’яті, як цього вимагає подвійний.


0

Цей приклад ілюструє, як витягти знак (крайній лівий біт), експонент (8 наступних біт) і мантісса (23 найправіші біти) з плаваючого на 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));

Цей же підхід можна використовувати і для подвійних (11-бітний показник і 52-бітова мантіса).

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

Кредит: http://sj.github.io/java-float/


0

Ви повинні використовувати подвійний замість float для точних обчислень, а float замість подвійних при використанні менш точних обчислень. Поплавок містить лише десяткові числа, але подвійний містить номер IEEE754 з подвійною точністю з плаваючою точкою, що полегшує точніше містити та обчислювати числа. Сподіваюсь, це допомагає.


0

У звичайних розрахунках програмування ми не використовуємо float. Якщо ми гарантуємо, що діапазон результатів знаходиться в діапазоні типу даних з плаваючою інформацією, то ми можемо вибрати тип даних з плаваючою здатністю для збереження пам'яті. Як правило, ми використовуємо подвійний з двох причин: -

  • Якщо ми хочемо використовувати число плаваючої точки як тип даних з плаваючою комою як тип даних з плаваючою комою, то виклик методу повинен явно суфіксом F або f, оскільки за замовчуванням кожне число з плаваючою комою розглядається як подвійне. Це збільшує навантаження на програміста. Якщо ми використовуємо номер з плаваючою комою як подвійний тип даних, тоді нам не потрібно додавати жоден суфікс.
  • Float - це одноточний тип даних, тобто він займає 4 байти. Отже, у великих обчисленнях ми не отримаємо повного результату. Якщо ми виберемо подвійний тип даних, він займає 8 байт, і ми отримаємо повні результати.

Як плаваючі, так і подвійні типи даних були розроблені спеціально для наукових розрахунків, де допустимі помилки апроксимації. Якщо точність є найбільшою проблемою, рекомендується використовувати клас BigDecimal замість плаваючих чи подвійних типів даних. Джерело: - Плаваючі та подвійні типи даних на Java

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.