A programozási tapasztalataim során gyakran el kell döntenem, hogy a float-ot vagy a double-t kell használnom az igazi számok. Néha úszni megyek, néha kettősre, de ez valóban szubjektívebb érzés. Ha szembesülnék a döntésem megvédésével, valószínűleg nem adnék megalapozott indokokat.
Mikor használod az úszót, és mikor a kettőt? Mindig kettőset használ, csak akkor, ha memóriahiányok vannak, akkor lebegjen? Vagy mindig úsztat, kivéve, ha a pontosság követelménye megkívánja a kettős használatát? Van-e lényeges különbség az alap aritemtika számítási komplexitása között az úszó és a kettős között? Milyen előnyei és hátrányai vannak a float vagy double használatának? És használtál már hosszú dupla?
Megjegyzések
- Sok esetben egyiket sem akarod használni, inkább tizedes lebegő vagy fixpontos típust. A bináris lebegőpontos típusok ‘ t nem képviselhetik pontosan a legtöbb tizedest.
- A témához kapcsolódóan ? . @CodesInChaos az én válaszom erőforrásokat javasol ennek a döntésnek a meghozatalában, nincs mindenre alkalmas megoldás .
- Mit értesz pontosan ” tizedesjegyek ” alatt. Ha pontosan olyan értékeket kell képviselnie, mint a 0,01 (mondjuk pénzért), akkor a (bináris) lebegőpont nem a válasz. Ha pusztán nem egész számokra gondol, akkor a lebegőpont valószínűleg rendben van – de akkor a ” tizedesjegyek ” nem a legjobb szó leírni, amire szüksége van.
- Figyelembe véve (mától kezdve) a legtöbb grafikus kártya elfogadja az úszókat a duplákon, a grafikus programozás gyakran egyetlen pontosságot használ.
- Ön nem ‘ nincs mindig választási lehetősége. Például az Arduino platformon a kettős és az úszó egyaránt egyenlő az úszással. Meg kell találnia egy kiegészítő könyvtárat a valós párosok kezeléséhez.
Válasz
Az alapértelmezett választás a lebegőpontos típusnak double
legyen. Ez az a típus is, amelyet utótag nélküli lebegőpontos literálokkal vagy (C-ben) lebegőpontos számokkal működő standard funkciókkal kap (pl. exp
, sin
stb.).
float
csak akkor szabad használni, ha sok lebegőpontos számmal kell operálni (gondoljon bele vagy több ezer nagyságrendű) és az algoritmus elemzése azt mutatta, hogy a csökkent tartomány és pontosság nem jelent problémát.
long double
akkor használható, ha nagyobb tartományra vagy pontosságra van szüksége, mint a double
, és ha ez biztosítja ezt a célplatformon.
Összefoglalva: float
és long double
-eket a szakemberek számára kell fenntartani, a double
-t pedig a “mindennapi” használatra.
Megjegyzések
- Valószínűleg nem gondolnám az úszást néhány ezer értéknél, kivéve, ha a lebegőpontos gyorsítótárhoz kapcsolódó teljesítményprobléma merül fel g és adatátvitel. Az elemzés elvégzésének általában jelentős költsége van annak bizonyítására, hogy az úszó elég pontos.
- Kiegészítésként előnyös lehet ugyanazokat az adattípusokat használni, ha kompatibilitásra van szüksége más rendszerekkel.
- I ‘ d számok millióit használom, nem pedig 1000-et. Emellett egyes GPU-k jobban járnak az úszókkal, ebben a speciális esetben úszókat használnak. Egyébként, ahogy mondod, használj duplákat.
- @PatriciaShanahan – ‘ teljesítményprobléma a következővel kapcsolatos: ‘ A jó példa, ha SSE2 vagy hasonló vektoros utasítások használatát tervezi, akkor 4 op / vektor lebegtetést tehet meg (szemben 2 duplánként), ami jelentős sebességjavulást eredményez (fele annyi op és fele annyi adat olvasható & írás). Ez jelentősen csökkentheti azt a küszöböt, ahol az úszók használata vonzóvá válik, és érdemes megtenni a fáradságot a numerikus kérdések rendezésében.
- Ezt a választ egy további tanáccsal támogatom: Ha RGB értékekkel működik a megjelenítés, akkor elfogadható az
float
(és esetenként félpontosság) használata, mert sem az emberi szem, a kijelző vagy a színrendszer nem rendelkezik ennyi pontossággal. Ez a tanács mondjuk az OpenGL-re stb. Vonatkozik. Ez a kiegészítő tanács nem vonatkozik az orvosi képekre, amelyek szigorúbb pontossági követelményekkel rendelkeznek.
Válasz
A modern számítógépeket célzó kódban ritkán van oka kettős helyett float használatának. Az extra pontosság csökkenti (de nem szünteti meg) a kerekítési hibák vagy más problémát okozó pontatlanság esélyét.
A float használatának legfőbb okai a következők lehetnek:
- nagy számú tömböt tárol, és csökkentenie kell a program memóriafogyasztását.
- Olyan rendszert céloz meg, amely natív módon nem támogatja a kettős pontosságú lebegőpontot. A közelmúltig sok grafikus kártya csak egyetlen precíziós lebegőpontot támogatott. Biztos vagyok benne, hogy rengeteg alacsony fogyasztású és beágyazott processzor rendelkezik, amelyeknek korlátozott lebegőpontos támogatása is van.
- Olyan hardvert céloz meg, ahol az egypontosság gyorsabb, mint a kettőspontosság, és az alkalmazása nagy igénybevételt jelent. A modern Intel CPU-kon úgy gondolom, hogy az összes lebegőpontos számítást kettős pontossággal végezzük, így itt nem nyer semmit.
- Alacsony szintű optimalizálást végez, például speciális CPU utasításokat használ, amelyek egyszerre több számot működtetnek.
Tehát alapvetően a kettős a módja annak, hogy menj, hacsak nincs hardverkorlátozásod, vagy ha az elemzés nem mutatta ki, hogy a dupla pontosságú számok tárolása jelentősen hozzájárul a memóriahasználathoz.
Megjegyzések
- ” Modern számítógépek ” Intel x86 processzorokat jelentenek. Az Ősök által használt gépek egy része tökéletesen pontos volt az alapvető úszó típushoz képest. (A CDC 6600 60 bites szót, 48 bit normalizált lebegőpontos mantisszát, 12 bit kitevőt használt. Ez ‘ MINDIG azt jelenti, amit az x86 kettős pontossággal megad.)
- @ John.R.Strohm: egyetértett, de a C fordítók nem léteztek a CDC6600-on. Ez volt a Fortran IV …
- ” modern számítógépeken ” minden olyan processzort értek, amelyet az elmúlt évtizedben építettek vagy kettő, vagy valóban, mivel az IEEE lebegőpontos szabványát széles körben alkalmazták. ‘ tökéletesen tisztában vagyok azzal, hogy léteznek nem x86 architektúrák, és ezt a válaszommal is szem előtt tartottam – megemlítettem a GPU-kat és a beágyazott processzorokat, amelyek általában nem x86-osok.
- Ez ‘ azonban egyszerűen nem igaz. Az SSE2 4 lebegő vagy 2 dupla műveletet képes kezelni egy művelet alatt, az AVX 8 úszt vagy 4 dupla, az AVX-512 16 lebegő vagy 8 dupla. Bármilyen nagyteljesítményű számítástechnika esetében az úszók matematikájának kétszerese kell lennie ugyanazon műveletek sebességének kétszeresein az x86-on.
- És ez ‘ s ennél is rosszabb, mivel kétszer annyi úszó fér el a processzor gyorsítótárában, mint duplákkal, és valószínűleg a memória késleltetése lesz a fő szűk keresztmetszet sok programban. Ha az egész úszó halmazot melegen tartja a gyorsítótárban, szó szerint nagyságrenddel gyorsabb lehet, mint a duplák használata és a RAM-ra ömlése.
Válasz
Használja a double
elemet az összes számításhoz és hőmérsékleti változóhoz. Használja az float
alkalmazást, ha számtömböt kell fenntartania – float[]
(ha a pontosság elegendő), és több mint tíz több ezer float
szám.
Sok / legtöbb matematikai függvény vagy operátor konvertál / ad vissza double
, és te nem ” a közbenső lépésekhez ne akarja visszaadni a számokat a float
helyre.
Pl. Ha 100 000 számot ad meg egy fájlból vagy egy adatfolyamból, és meg kell rendezze őket, tegye a számokat egy float[]
helyre.
Válasz
Néhány platform (ARM Cortex-M2, Cortex-M4 stb.) Nem támogat double (Mindig ellenőrizhető a referencia kézikönyvben Ha nincs fordítási figyelmeztetés vagy hiba, ez nem jelenti azt, hogy a kód optimális. double emulálható .) Ezért lehet, hogy ragaszkodnia kell a int vagy float .
Ha nem ez a helyzet, akkor a double -t használnám.
Megtekintheti D. Goldberg híres cikkét (“Mit kell minden számítógépes tudósnak tudnia a lebegőpontos számtanról”). Kétszer is el kell gondolkodnia, mielőtt lebegőpontos aritmetikát alkalmazna. Elég nagy az esély arra, hogy az adott helyzetben egyáltalán nincs szükség rájuk.
http://perso.ens-lyon.fr/jean-michel.muller/goldberg.pdf
Megjegyzések
- Erre a kérdésre már egy éve nagyon jól válaszoltak …de mindenesetre azt mondom, hogy ‘ bármikor ‘ dupla dupla pontosságú FPU-gyorsítással rendelkező platformokon használ, akkor használnia kell bármi másra, még akkor is, ha ez azt jelenti, hogy hagyjuk a fordítót utánozni, ahelyett, hogy csak lebegőpontos FPU-t használnánk (vegye figyelembe, hogy az FPU ‘ s nem ‘ ez sem szükséges minden platformon, valójában a Cortex-M4 architektúra opcionális szolgáltatásként definiálja őket [az M2 elírás volt?]).
- Ennek a logikának a kulcsa az, ‘ igaznak el kell fáradnia a lebegőpontos aritmetikától, és ‘ sok ” quirks “, az FPU támogatásának jelenlétét a párosoknál biztosan nem úgy értjük, hogy egyszerűen úszók helyett duplákat használunk. Az úszások általában gyorsabbak, mint a duplák, és kevesebb memóriát igényelnek (az FPU funkciói eltérnek). A felhasználás mennyisége kizárja, hogy ez a pont idő előtti optimalizálást alkalmazzon. Ahogy az a tény, hogy a duplák egyértelműen túlteljesek sok (talán a legtöbb) alkalmazásnál. Az ezen az oldalon található elemek relatív helyzetét és méretét valóban 13 tizedesjegyig kell számítani?
- Ha egy webhelyen kívüli oldalra vagy dokumentumra mutató linket tartalmaz, kérjük, másolja a vonatkozó információt vagy összefoglalót a dokumentumból a válaszába. A webhelyen kívüli linkek hajlamosak eltűnni az idő múlásával.
Válasz
Valósági problémák esetén a mintavételi küszöbérték az Ön adatai fontosak a kérdés megválaszolásakor. Hasonlóképpen a zajszint is fontos. Ha bármelyiket túllépi az adattípus kiválasztása, akkor a pontosság növelése nem jár előnyökkel.
A legtöbb valós mintavevő 24 bites DAC-ra korlátozódik. Azt javasolva, hogy a valós számításoknál 32 bites pontosságnak megfelelőnek kell lennie, ha a szignifikancia 24 bites pontosságú.
A dupla pontosság kétszeres memória árával jár. Ezért a duplák használatának korlátozása az úszók felett drasztikusan csökkentheti a futó alkalmazások memóriaterületét / sávszélességét.
Válasz
A hogy az úszó és a dupla között milyen változót kell használni, az a szükséges adatok pontosságától függ. Ha a válasznak elenyésző különbséggel kell rendelkeznie a tényleges választól, akkor a szükséges tizedesjegyek száma sok lesz, így ez a dupla diktálható lesz. A Float levág néhány tizedesjegy pontot, csökkentve ezzel a pontosságot.
Megjegyzések
- Ez a válasz nem ad hozzá ‘ semmi újat a kérdéshez, és nem mond el semmit a tényleges használatról.
Válasz
Általában a float
típust használom Nincs szükségem nagy pontosságra – például pénzért – ami helytelen, de ezt szoktam rosszul csinálni.
Másrészt a amikor nagyobb pontosságra van szükségem, például összetett matematikai algoritmusok esetén.
A C99 szabvány ezt mondja:
Három lebegőpontos típus létezik: úszó, kettős és hosszú kettős. A kettős típus legalább akkora pontosságot nyújt, mint az úszó, a hosszú kettős pedig legalább akkora pontosságot, mint a kettős. A float típusú értékkészlet a double típusú értékhalmaz részhalmaza; a double típusú értékkészlet a long double típusú értékkészlet részhalmaza.
Soha nem használtam long double
, de annyira nem használom a C / C ++ -t. Általában olyan dinamikusan beírt nyelveket használok, mint a Python, ahol nem kell törődni a típusokkal.
A Double vs Float ról további információkért lásd: ezt a kérdést a SO-nál .
Megjegyzések
- A lebegőpontos felhasználás komoly pénzszámításokhoz valószínűleg hiba.
- A float pontosan nem megfelelő típusú pénz. A lehető legnagyobb pontosságot kell használnia.
- @BartvanIngenSchenau A pénz lebegőpontja általában rendben van, a bináris lebegőpont nem. Például .net ‘ s
Decimal
egy lebegőpontos típus, és általában ‘ s jó választás pénzszámításhoz. - @ChrisF Nem kell ‘ nem kell ” nagy pontosságú ” pénzért pontos értékekre van szüksége.
- @SeanMcSomething – Igazságos pont. Az úszók azonban még mindig nem megfelelő típusúak, és a legtöbb nyelvben elérhető lebegőpontos típusok miatt ” nagy pontosságú ” szükséges a ” pontos értékek “.