Ofte i min programmeringserfaring er jeg nødt til at træffe en beslutning om jeg skal bruge float eller double for mit virkelige numre. Nogle gange går jeg for float, nogle gange går jeg for dobbelt, men det føles virkelig mere subjektivt. Hvis jeg ville blive konfronteret med at forsvare min beslutning, ville jeg sandsynligvis ikke give gode grunde.
Hvornår bruger du float, og hvornår bruger du dobbelt? Bruger du altid dobbelt, kun når du har hukommelsesbegrænsninger, skal du flyde? Eller bruger du altid float, medmindre præcisionskravet kræver, at du bruger dobbelt? Er der nogle væsentlige forskelle med hensyn til beregningskompleksitet af grundlæggende aritemtik mellem float og double? Hvad er fordele og ulemper ved at bruge float eller double? Og har du endda brugt lange dobbelt?
Kommentarer
- I mange tilfælde vil du ikke bruge nogen af dem, men snarere en decimal flydende eller fast punkt type. Binære flydende punkttyper kan ‘ t repræsenterer de fleste decimaler nøjagtigt.
- Relateret til Hvad forårsager afrundingsfejl med flydende punkt ? . @CodesInChaos mit svar der foreslår ressourcer til at hjælpe dig med at beslutte, der er ingen one-size-fits-all løsning.
- Hvad mener du præcist med ” decimaler “. Hvis du har brug for at repræsentere værdier som 0,01 nøjagtigt (f.eks. For penge), er (binært) flydende punkt ikke svaret. Hvis du blot betyder ikke-heltal, er flydende punkt sandsynligvis ok – men så er ” decimaler ” ikke det bedste ord for at beskrive, hvad du har brug for.
- I betragtning af (fra i dag) accepterer de fleste grafikkort svømmer over dobbelt, grafikprogrammering bruger ofte en enkelt præcision.
- Du don ‘ har ikke altid et valg. For eksempel på Arduino-platformen svarer både dobbelt og flyde til at flyde. Du skal finde et tilføjelsesbibliotek til at håndtere ægte fordoblinger.
Svar
Standardvalget for en flydende punkt-type skal være double
. Dette er også den type, du får med flydende bogstaver uden suffiks eller (i C) standardfunktioner, der fungerer på flydende numre (f.eks. exp
, sin
osv.).
float
bør kun bruges, hvis du har brug for at arbejde på mange flydende numre (tænk i rækkefølgen af tusinder eller mere) og analyse af algoritmen har vist, at det reducerede interval og nøjagtighed ikke udgør et problem.
long double
kan bruges, hvis du har brug for mere rækkevidde eller nøjagtighed end double
, og hvis den giver dette på din målplatform.
Sammenfattende float
og long double
skal reserveres til brug af specialisterne med double
til “hver dag” brug.
Kommentarer
- Jeg vil sandsynligvis ikke overveje at flyde for et par tusinde værdier, medmindre der var et ydeevne problem relateret til flydende cachin g og dataoverførsel. Der er normalt en betydelig omkostning ved at udføre analysen for at vise, at float er præcis nok.
- Som et tillæg, hvis du har brug for kompatibilitet med andre systemer, kan det være en fordel at bruge de samme datatyper.
- Jeg ‘ bruger flåder til millioner af numre, ikke 1000ere. Nogle GPUer klarer sig også bedre med floats, i det specialiserede tilfælde bruger floats. Ellers skal du, som du siger, bruge dobbelt.
- @PatriciaShanahan – ‘ ydeevne problem relateret til .. ‘ A godt eksempel er, hvis du planlægger at bruge SSE2 eller lignende vektorinstruktioner, kan du lave 4 ops / vektor i float (vs 2 pr. dobbelt), hvilket kan give en betydelig hastighedsforbedring (halvt så mange ops og halvt så mange data at læse & skriv). Dette kan sænke tærsklen betydeligt, hvor brug af floats bliver attraktivt, og det er værd at gøre det for at sortere de numeriske problemer.
- Jeg støtter dette svar med et ekstra råd: Når man arbejder med RGB-værdier til visning, er det er acceptabelt at bruge
float
(og lejlighedsvis halvpræcision), fordi hverken det menneskelige øje, skærmen eller farvesystemet har så mange bit af præcision. Dette råd gælder f.eks. OpenGL osv. Dette yderligere råd gælder ikke for medicinske billeder, der har strengere præcisionskrav.
Svar
Der er sjældent grund til at bruge float i stedet for dobbelt i kode, der er målrettet mod moderne computere. Den ekstra præcision reducerer (men eliminerer ikke) chancen for afrundingsfejl eller anden upræcision, der forårsager problemer.
Hovedårsagerne til, at jeg kan tænke mig at bruge float, er:
- Du gemmer store talrække og har brug for at reducere dit programs hukommelsesforbrug.
- Du målretter mod et system, der ikke understøtter indbygget flydepunkt med dobbelt præcision. Indtil for nylig understøttede mange grafikkort kun enkeltpræcisions flydepunkter. Jeg er sikker på, at der er masser af processorer med lav effekt og indlejrede, der også har begrænset flydepunktsunderstøttelse.
- Du målretter mod hardware, hvor enkeltpræcision er hurtigere end dobbeltpræcision, og din applikation bruger tungt af flydende aritmetik. På moderne Intel-CPUer tror jeg, at alle flydende beregninger udføres i dobbelt præcision, så du får ikke noget her.
- Du foretager optimering på lavt niveau, for eksempel ved hjælp af specielle CPU-instruktioner, der fungerer på flere numre ad gangen.
Så grundlæggende er dobbelt måde at gå medmindre du har hardwarebegrænsninger, eller medmindre analyse har vist, at lagring af dobbelt præcisionstal bidrager væsentligt til hukommelsesforbrug.
Kommentarer
- ” Moderne computere ” betyder Intel x86-processorer. Nogle af de maskiner, de gamle brugte, leverede perfekt tilstrækkelig præcision med den grundlæggende flydetype. (CDC 6600 brugte et 60-bit ord, 48 bit normaliseret float-point mantissa, 12 bits eksponent. At ‘ er næsten hvad x86 giver dig til dobbelt præcision.)
- @ John.R.Strohm: aftalt, men C-kompilatorer eksisterede ikke på CDC6600. Det var Fortran IV …
- Af ” moderne computere ” Jeg mener enhver processor bygget i det sidste årti eller to, eller virkelig, da IEEE floating point-standarden blev implementeret bredt. Jeg ‘ er helt klar over, at der ikke findes x86-arkitekturer og havde det i tankerne med mit svar – Jeg nævnte GPUer og indlejrede processorer, som typisk ikke er x86.
- At ‘ ganske enkelt ikke er sandt. SSE2 kan manipulere 4 floats eller 2 doubles i en operation, AVX kan manipulere 8 floats eller 4 doubles, AVX-512 kan manipulere 16 floats eller 8 doubles. For enhver form for højtydende computing skal matematik på floats betragtes som dobbelt så hurtigt som de samme operationer på fordobling på x86.
- Og det ‘ s endnu værre end det, da du kan passe dobbelt så mange flyder i processorens cache som du kan med dobbelt, og hukommelsestiden sandsynligvis vil være den vigtigste flaskehals i mange programmer. At holde et helt fungerende sæt floats varmt i cachen kan være bogstaveligt talt en størrelsesorden hurtigere end at bruge dobbelt og få dem til at spildes til RAM.
Svar
Brug double
til alle dine beregninger og tempvariabler. Brug float
, når du har brug for at opretholde en række tal – float[]
(hvis præcision er tilstrækkelig), og du har at gøre med over snesevis af tusinder af float
numre.
Mange / de fleste matematiske funktioner eller operatorer konverterer / returnerer double
, og du don ” t ønsker at kaste numrene tilbage til float
for ethvert mellemliggende trin.
F.eks. Hvis du har en input på 100.000 numre fra en fil eller en stream og har brug for sorter dem, sæt tallene i et float[]
.
Svar
Nogle platforme (ARM Cortex-M2, Cortex-M4 osv.) Understøtter ikke dobbelt (Det kan altid kontrolleres i referencevejledningen til din processor. Hvis der ikke er nogen kompilationsadvarsler eller fejl, betyder det ikke, at koden er optimal. dobbelt kan efterlignes .). Derfor skal du muligvis holde dig til int eller float .
Hvis det ikke er tilfældet, bruger jeg dobbelt .
Du kan tjekke den berømte artikel af D. Goldberg (“Hvad enhver computerforsker burde vide om flydende aritmetik”). Du bør tænke to gange, før du bruger flydende aritmetik. Der er en ret stor chance for, at de slet ikke er nødvendige i din særlige situation.
http://perso.ens-lyon.fr/jean-michel.muller/goldberg.pdf
Kommentarer
- Dette spørgsmål blev allerede besvaret ret godt for et år siden …men under alle omstændigheder siger jeg ‘ når som helst du ‘ bruger dobbelt på platforme med dobbelt præcision FPU-acceleration, skal du bruge det på enhver anden, selvom det betyder at lade kompilatoren emulere det i stedet for at udnytte en FPU med kun flydende punkt (bemærk, at FPU ‘ er ‘ kræves heller ikke på alle platforme, faktisk definerer en Cortex-M4-arkitektur dem som en valgfri funktion [var M2 en skrivefejl?]).
- Nøglen til denne logik er, mens det ‘ s sandt man skal være træt af flydende aritmetik, og det ‘ er mange ” quirks “, bestemt ikke tager tilstedeværelsen af FPU-understøttelse for double for at betyde, at du bare bruger double i stedet for floats. Flyder er generelt hurtigere end dobbelt og tager mindre hukommelse (FPU-funktionerne varierer). Mængden af brug udelukker, at dette punkt er i for tidlig optimering. Ligesom det faktum er dobbelt klart overdreven til mange (måske endda de fleste) applikationer. Skal elementerne på denne side virkelig have deres relative positioner og størrelser beregnet til 13 decimaler?
- Når du inkluderer et link til en off-site-side eller et dokument, skal du kopiere relevant information eller resumé fra dokumentet til dit svar. Off-site links har en tendens til at forsvinde over tid.
Svar
For problemer i den virkelige verden er prøvetagningstærsklen for dine data er vigtige, når du besvarer dette spørgsmål. Tilsvarende er støjgulvet også vigtigt. Hvis begge dele overskrides af dit datatypevalg, vil der ikke være nogen fordel ved at øge præcisionen.
De fleste samplere fra den virkelige verden er begrænset til 24 bit DACer. Foreslå, at 32 bit præcision på beregninger i den virkelige verden skal være tilstrækkelig, hvor betydningen er 24 bit præcision.
Dobbelt præcision koster 2x hukommelse. Derfor kan begrænsning af brugen af dobbelt over floats drastisk reducere hukommelsesfodaftryk / båndbredde for kørende applikationer.
Svar
Valget af hvilken variabel der skal bruges mellem float og double afhænger af nøjagtigheden af de krævede data. Hvis det kræves, at et svar har en ubetydelig forskel fra det faktiske svar, vil antallet af decimaler, der kræves, være mange, hvilket vil diktere, at det dobbelte skal være i brug. Flåden hugger nogle del af decimaler af og reducerer nøjagtigheden.
Kommentarer
- Dette svar tilføjer ikke ‘ noget nyt til spørgsmålet og siger ikke noget om faktisk brug.
Svar
Normalt bruger jeg float
typen, når Jeg har ikke brug for meget præcision – for eksempel for penge – hvilket er forkert, men det er det, jeg plejede at gøre forkert.
På den anden side bruger jeg double
når jeg har brug for mere præcision, for eksempel for komplekse matematiske algoritmer.
C99-standarden siger dette:
Der er tre typer flydende punkter: flyde, dobbelt og langt dobbelt. Typen dobbelt giver mindst lige så meget præcision som flyde, og typen lang dobbelt giver mindst lige så meget præcision som dobbelt. Sættet med værdier af typen float er et undersæt af det sæt af værdier af typen double; værdisættet af typen dobbelt er en delmængde af værdisættet af typen lang dobbelt.
Jeg har aldrig rigtig brugt long double
, men jeg bruger ikke C / C ++ så meget. Normalt bruger jeg dynamisk typede sprog som Python, hvor du ikke behøver at bekymre dig om typerne.
For yderligere information om Double vs Float , se dette spørgsmål på SO .
Kommentarer
- Brug af floating point til seriøse pengeberegninger er sandsynligvis en fejltagelse.
- float er nøjagtigt den forkerte type for penge. Du skal bruge den højest mulige præcision.
- @BartvanIngenSchenau Flydepunkt for penge er normalt okay, binært flydende punkt er ikke. For eksempel .net ‘ s
Decimal
er en flydende punktstype, og den ‘ er typisk et godt valg til pengeudregninger. - @ChrisF Du behøver ikke ‘ t ” høj præcision ” for pengene, du har brug for nøjagtige værdier.
- @SeanMcSomething – Fair point. Imidlertid er floats stadig den forkerte type og givet de flydende punkttyper, der er tilgængelige på de fleste sprog, har du brug for ” høj præcision ” for at få ” nøjagtige værdier “.