Różnica między zmiennoprzecinkowym a podwójnym - którego należy użyć?

(Uwaga: w tym artykule założono, że czytelnicy znają podstawy informatyki)

Wielu początkujących programistów / studentów, którzy są zapisani na informatykę, zadaje często zadawane pytania, które są istotne dla konkretnej dziedziny informatyki, którą studiują. Większość kursów dla początkujących zaczyna się od tematów systemu liczbowego stosowanego we współczesnych komputerach, w tym dwójkowy, dziesiętny, ósemkowy i szesnastkowy system. Są to formaty liczbowe komputerów, które są wewnętrznymi reprezentacjami wartości liczbowych w komputerach (lub kalkulatorach i innych komputerach cyfrowych). Wartości te są przechowywane jako „grupa bitów”.

Jak wiemy, komputery reprezentują dane w zestawach cyfr binarnych (tj. W kombinacji 1s i 0s, Jak na przykład, 1111 reprezentuje 15 w systemie dziesiętnym) sensowne jest nauczanie o różnych formatach liczb używanych do reprezentowania dynamicznego zakresu wartości, ponieważ tworzą one podstawowe bloki obliczeń / przetwarzania liczb w dowolnej operacji. Po zdefiniowaniu systemu liczb w klasie (często źle) uczniowie mają pokusę, aby przejść do różnych formatów liczb w tym samym typie (tj.., arytmetyka zmiennoprzecinkowa), które mają pewną precyzję i zakres liczb. W związku z tym są zmuszeni nauczyć się niuansów między niektórymi typami. Dwa najczęściej używane typy danych to Pływak i Podwójnie, i chociaż zaspokajają te same potrzeby (tj., arytmetyka zmiennoprzecinkowa), istnieją dość pewne różnice w ich wewnętrznej reprezentacji i ogólnym wpływie na obliczenia w programie. Szkoda, że ​​wielu programistów nie dostrzega niuansów między typami danych Flat i Double i ostatecznie niewłaściwie je wykorzystuje w miejscach, w których nie należy ich używać. Ostatecznie prowadzi to do błędnych obliczeń w innych częściach programu.

W tym artykule wyjaśnię różnicę między zmiennoprzecinkową i podwójną za pomocą przykładów kodu w języku programowania C. Zacznijmy!

Float vs Double… O co chodzi?

Liczby zmiennoprzecinkowe i podwójne to reprezentacje danych używane w operacjach arytmetycznych zmiennoprzecinkowych, pomyśl o liczbach dziesiętnych obliczanych w klasie matematycznej, takich jak, 20.123, 16,23, 10.2, itp., nie są to liczby całkowite (tj., 2), 5, 15, itd.), dlatego wymagają uwzględnienia ułamków binarnych. Jako wynikowe liczby dziesiętne (tj., 20.123, 16,23, itp.) nie można łatwo przedstawić za pomocą normalnego formatu binarnego (tj. Integer). Główną różnicą między zmiennoprzecinkowymi i podwójnymi jest to, że te pierwsze to dane zmiennoprzecinkowe pojedynczej precyzji (32-bitowe), podczas gdy drugie to dane zmiennoprzecinkowe podwójnej precyzji (64-bitowe). Double nazywa się „double”, ponieważ jest to w zasadzie wersja Float z podwójną precyzją. Jeśli obliczasz ogromną ilość (pomyśl o tysiącach zer w liczbie), niedokładności będą mniejsze w Double i nie stracisz dużej precyzji.

Lepiej jest rozwinąć za pomocą przykładów kodu. Poniżej przedstawiono operacje na Float i Double za pomocą funkcji matematycznych w języku C:

#zawierać

int main ()

zmiennoprzecinkowa num1 = 1.f / 82;

liczba zmiennoprzecinkowa 2 = 0;

dla (int i = 0; i < 738; ++i)

num2 + = num1;

printf („%. 7g \ n”, num2);

podwójna liczba 3 = 1,0 / 82;

podwójne num4 = 0;

dla (int i = 0; i < 738; ++i)

num4 + = num3;

printf („%. 15g \ n”, num4);

getchar ();

Drukuje następujące:

9,000031

8,9999999999999983

Tutaj widać, że niewielka różnica w precyzji Float i Double daje zupełnie inną odpowiedź, choć Double wydaje się być dokładniejsza niż Float.

Oto przykład funkcji sqrt () w C:

#zawierać

#zawierać

int main ()

zmiennoprzecinkowa num1 = sqrt (2382719676512365.1230112312312312);

double num2 = sqrt (2382719676512365.1230112312312312);

printf („% f \ n”, num1);

printf („% f \ n”, num2);

getchar ();

Daje następujące dane wyjściowe:

48813108.000000

48813109.678778

Tutaj widać, że odpowiedź w Double ma lepszą precyzję.

Podsumowując, lepiej jest używać Double do arytmetyki zmiennoprzecinkowej, ponieważ kilka standardowych funkcji matematycznych w C działa na Double, a nowoczesne komputery są niezwykle szybkie i wydajne do obliczeń zmiennoprzecinkowych Double. Prowadzi to do zmniejszenia potrzeby używania zmiennoprzecinkowego, chyba że musisz operować na wielu liczbach zmiennoprzecinkowych (pomyśl o dużych tablicach z tysiącami zer w liczbach) lub działasz w systemie, który nie obsługuje podwójnego- precyzja zmiennoprzecinkowa, ponieważ wiele procesorów graficznych, urządzeń o niskiej mocy i niektórych platform (ARM Cortex-M2, Cortex-M4 itp.) nie obsługuje jeszcze Double, dlatego powinieneś użyć Float. Dodatkowo należy pamiętać, że niektóre procesory graficzne / procesory działają lepiej / wydajniej w przetwarzaniu zmiennoprzecinkowym, np. W obliczeniach wektorów / macierzy, więc może zajść potrzeba zajrzenia do instrukcji / dokumentacji specyfikacji sprzętu, aby lepiej zdecydować, którego z nich należy użyć dla konkretnej maszyny.

Rzadko jest powód, aby używać Float zamiast Double w kodzie kierowanym na nowoczesne komputery. Dodatkowa precyzja w Double zmniejsza, ale nie eliminuje, możliwości zaokrąglania błędów lub innych niedokładności, które mogą powodować problemy w innych częściach programu. Wiele funkcji matematycznych lub operatorów konwertuje i zwraca Double, więc nie trzeba rzutować liczb na Float, ponieważ może to stracić precyzję. Aby uzyskać szczegółową analizę arytmetyki zmiennoprzecinkowej, gorąco polecam przeczytanie tego niesamowitego artykułu (http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html).

streszczenie

Więc… w skrócie:

Miejsca, w których powinieneś używać Float:

  • Jeśli celujesz w sprzęt, w którym pojedyncza precyzja jest szybsza niż podwójna precyzja.
  • Twoja aplikacja intensywnie korzysta z arytmetyki zmiennoprzecinkowej, takiej jak tysiące liczb z tysiącami zer.
  • Robisz optymalizację na bardzo niskim poziomie. Na przykład używasz specjalnych instrukcji procesora (tj. SSE, SSE2, AVX itp.), Które działają na wielu liczbach / tablicach / wektorach jednocześnie.

Wniosek

W tym artykule podkreśliłem różnicę między Float i Double, a która powinna być używana w określonych miejscach. Prawdopodobnie lepiej jest używać Double w większości miejsc na ślepo, zwłaszcza jeśli atakujesz nowoczesne komputery, ponieważ szanse na niską wydajność ze względu na zastosowanie arytmetyki zmiennoprzecinkowej Double są bardzo mało prawdopodobne. Jeśli masz jakieś pytania, możesz je zadać w sekcji komentarzy poniżej!