Skirtumas tarp plūduriuojančio ir dvigubo - kurį turėčiau naudoti?

(Pastaba: šiame straipsnyje daroma prielaida, kad skaitytojai žino apie kompiuterių mokslo pagrindus)

Daugelis naujokų programuotojų / studentų, įstojusių į kompiuterių mokslą, užduoda dažnai užduodamus klausimus, susijusius su konkrečia informatikos sritimi, kurią jie studijuoja. Daugelis pradedančiųjų kursų prasideda skaičiaus sistemos, naudojamos šiuolaikiniuose kompiuteriuose, įskaitant temas, temomis dvejetainis, skaitmenų po kablelio, aštuonkojis ir šešioliktainis sistema. Tai yra kompiuterio numerio formatai, kurie yra skaitmeninių verčių vidiniai vaizdai kompiuteriuose (arba skaičiuotuvuose ir bet kokiuose kituose skaitmeniniuose kompiuteriuose). Šios vertės saugomos kaip „bitų grupavimas“.

Kaip mes žinome, kompiuteriai vaizduoja duomenis dvejetainių skaičių rinkinyje (t. Y. Kartu 1 s ir 0s, toks kaip, 1111 atstovauja 15 dešimtainėje sistemoje), prasminga mokyti apie įvairius skaičių formatus, kurie naudojami atvaizduoti dinaminį verčių diapazoną, nes jie sudaro pagrindinius skaičiavimo / skaičiaus apdorojimo blokus bet kokio tipo operacijose. Kai klasių klasėje bus apibrėžta skaičių sistema (dažnai prastai), mokiniams kyla pagunda pereiti prie skirtingų to paties tipo skaičių formatų (t. Y.., slankiojo kablelio aritmetika), kurie turi tam tikrą tikslumą ir skaičių diapazoną. Taigi jie yra priversti išmokti tam tikrų tipų niuansų. Du dažniausiai naudojami duomenų tipai Plūdė ir Dviguba, ir nors jie nukreipti į tuos pačius poreikius (t., slankiojo kablelio aritmetika), skiriasi vidinis jų vaizdas ir bendras poveikis skaičiavimams programoje. Gaila, kad daugelis programuotojų praleidžia „Flat“ ir „Double“ duomenų tipų niuansus ir galų gale juos netinkamai naudoja vietose, kur jie neturėtų būti naudojami pirmiausia. Galiausiai klaidingi skaičiavimai kitose programos dalyse.

Šiame straipsnyje aš jums papasakosiu skirtumą tarp „float“ ir „double“ su kodų pavyzdžiais C programavimo kalba. Pradėkime!

Plūdės vs dvigubai ... Koks susitarimas?

Plūduriuojantis ir dvigubasis yra duomenų vaizdavimas, naudojamas aritmetinėms slankiojo kablelio operacijoms, pagalvokite apie dešimtainius skaičius, kuriuos apskaičiavote matematikos klasėje, pavyzdžiui, 20.123, 16.23, 10.2, tt, jie nėra sveikieji skaičiai (t. y., 2, 5, 15, ir tt), todėl reikia atsižvelgti į trupmenas dvejetainėje. Kaip gaunami dešimtainiai skaičiai (t., 20.123, 16.23, t.) negali būti lengvai pavaizduota įprastu dvejetainiu formatu (t. y. sveikasis skaičius). Pagrindinis skirtumas tarp slankiojo kablelio ir dvigubo yra tas, kad pirmasis yra vieno tikslumo (32 bitų) slankiojo kablelio duomenys, o antrasis yra dvigubo tikslumo (64 bitų) slankiojo kablelio duomenų tipas. Dviguba vadinama „dviguba“, nes iš esmės tai yra dvigubai tiksli „Float“ versija. Jei skaičiuojate didžiulę sumą (pagalvokite tūkstančius 0 skaičiaus), dvigubai netikslumai bus mažesni ir neprarasite daug tikslumo.

Geriau paaiškinti naudojant kodų pavyzdžius. Tai yra veiksmas naudojant „Float“ ir „Double“ per matematikos funkcijas, pateiktas C kalba:

# įtraukti

int pagrindinis ()

plūdės numeris1 = 1.f / 82;

plūdė num2 = 0;

už (int i = 0; i < 738; ++i)

num2 + = num1;

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

dvigubas num3 = 1,0 / 82;

dvigubas num4 = 0;

už (int i = 0; i < 738; ++i)

num4 + = num3;

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

getčaras ();

Tai spausdinama taip:

9.000031

8.99999999999983

Čia galite pastebėti, kad nedidelis „Float“ ir „Double“ tikslumo skirtumas pateikia visai kitokį atsakymą, nors „Double“ atrodo tikslesnis nei „Float“.

Toliau pateiktas funkcijos sqrt () C pavyzdys:

# įtraukti

# įtraukti

int pagrindinis ()

plūdės numeris1 = sqrt (2382719676512365.1230112312312312);

dvigubas num2 = sqrt (2382719676512365.1230112312312312);

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

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

getčaras ();

Tai duoda tokią išvestį:

48813108.000000

48813109.678778

Čia galite pamatyti, kad atsakymas dvigubai tiksliau.

Apskritai, geriau naudoti dvigubą slankiojo kablelio aritmetiką, nes kelios standartinės C matematikos funkcijos veikia dvigubai, o šiuolaikiniai kompiuteriai yra ypač greiti ir veiksmingi dvigubo slankiojo kablelio skaičiavimams. Dėl to sumažėja poreikis naudoti spartųjį kintamąjį, nebent jums reikia naudoti daugybę slankiųjų kablelių skaičių (pagalvokite apie didelius masyvus, turinčius tūkstančius 0 skaičių) arba jei dirbate sistemoje, kuri nepalaiko dvigubo tikslus slankiojo kablelio taškas, nes daugelis GPU, mažai energijos naudojančių įrenginių ir tam tikrų platformų (ARM Cortex-M2, Cortex-M4 ir kt.) dar nepalaiko „Double“, tuomet turėtumėte naudoti „float“. Be to, reikia atsiminti vieną dalyką: kai kurie GPU / CPU veikia geriau / efektyviau naudojant „Float“ apdorojimą, pavyzdžiui, apskaičiuojant vektorius / matricą, todėl jums gali reikėti ieškoti aparatūros specifikacijos vadovo / dokumentacijos, kad geriau nuspręstumėte, kurį iš jų turėtumėte naudoti. tam tikrai mašinai.

Modernaus kompiuterio kode retai yra priežastis naudoti „Float“, o ne „Double“. Papildomas „Double“ tikslumas sumažina apvalinimo klaidų ar kitų netikslumų, galinčių sukelti problemų kitose programos dalyse, galimybę, tačiau jų nepašalina. Daugybė matematikos funkcijų ar operatorių konvertuoja ir grąžina dvigubą, todėl jums nereikia perduoti skaičių atgal į „Float“, nes tai gali prarasti tikslumą. Norėdami atlikti išsamią slankiojo kablelio aritmetikos analizę, labai rekomenduoju perskaityti šį nuostabų straipsnį (http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html).

Santrauka

Taigi ... Trumpai tariant:

Vietos, kuriose turėtumėte naudoti „Float“:

  • Jei taikote į aparatinę įrangą, kur vieno tikslumo spartumas yra didesnis nei dvigubo tikslumo.
  • Tavo programa naudoja daugiasykį slankiojo kablelio aritmetiką, pavyzdžiui, tūkstančius skaičių su tūkstančiais 0.
  • Jūs darote labai žemą optimizavimą. Pavyzdžiui, jūs naudojate specialias CPU instrukcijas (t. Y. SSE, SSE2, AVX ir kt.), Kurios veikia keliais skaičiais / matricomis / vektoriais vienu metu.

Išvada

Šiame straipsnyje aš išryškinau skirtumą tarp „Float“ ir „Double“ ir kuris iš jų turėtų būti naudojamas konkrečiose vietose. Be abejo, daugumoje vietų geriau naudoti aklai, ypač jei orientuojatės į šiuolaikinius kompiuterius, nes mažai tikėtina, kad naudojant dvigubą slankiojo kablelio aritmetiką bus mažas efektyvumas. Jei turite klausimų, galite jų užduoti žemiau esančiame komentarų skyriuje!