Ofte i programmeringsopplevelsen min, må jeg ta en beslutning om jeg skal bruke float eller double for mitt virkelige tall. Noen ganger går jeg for float, noen ganger går jeg for dobbel, men egentlig føles dette mer subjektivt. Hvis jeg blir konfrontert for å forsvare avgjørelsen min, ville jeg sannsynligvis ikke oppgi gode grunner.

Når bruker du float og når bruker du dobbelt? Bruker du alltid dobbelt, bare når du har minnebegrensninger, vil du flyte? Eller bruker du alltid float med mindre presisjonskravet krever at du bruker dobbelt? Er det noen vesentlige forskjeller med hensyn til beregningskompleksitet av grunnleggende aritemikk mellom float og double? Hva er fordelene og ulempene med å bruke flyte eller dobbelt? Og har du til og med brukt lange doble?

Kommentarer

  • I mange tilfeller vil du bruke ingen av dem, men heller en desimal flytende eller fast punkt type. Binære flytpunkttyper kan ‘ t representerer de fleste desimaler nøyaktig.
  • Relatert til Hva forårsaker feil med avrunding av flytende punkt ? . @CodesInChaos mitt svar der foreslår ressurser som hjelper deg med å ta den beslutningen, det er ingen en-størrelse-passer-alle løsning.
  • Hva mener du nøyaktig med » desimaler «. Hvis du trenger å representere verdier som 0,01 nøyaktig (si for penger), er ikke (binært) flytende punkt svaret. Hvis du bare betyr tall som ikke er heltall, er det sannsynlig at flytende punkt er ok – men da er » desimaler » ikke det beste ordet for å beskrive det du trenger.
  • Med tanke på (per i dag) aksepterer de fleste grafikkort flyter over dobler, grafikkprogrammering bruker ofte en enkelt presisjon.
  • Du trenger ikke ‘ t har alltid et valg. For eksempel, på Arduino-plattformen, tilsvarer både dobbel og flottør å flyte. Du må finne et tilleggsbibliotek for å håndtere ekte dobler.

Svar

Standardvalget for et flytende punkt-typen skal være double. Dette er også typen du får med flytende bokstavsbokstaver uten suffiks eller (i C) standardfunksjoner som fungerer på flytende punktum (f.eks. exp, sin osv.).

float bør bare brukes hvis du trenger å operere på mange flytende tall (tenk på rekkefølgen av tusenvis eller mer) og analyse av algoritmen har vist at redusert rekkevidde og nøyaktighet ikke utgjør et problem.

long double kan brukes hvis du trenger mer rekkevidde eller nøyaktighet enn double, og hvis den gir dette på målplattformen din.

Oppsummert, float og long double bør reserveres for bruk av spesialistene, med double for «hverdags» bruk.

Kommentarer

  • Jeg vil sannsynligvis ikke vurdere å flyte for noen få tusen verdier med mindre det var et ytelsesproblem relatert til flytende punkt cachin g og dataoverføring. Det er vanligvis en betydelig kostnad å gjøre analysen for å vise at flyt er nøyaktig nok.
  • Som et tillegg, hvis du trenger kompatibilitet med andre systemer, kan det være fordelaktig å bruke de samme datatypene.
  • Jeg ‘ bruker flater for millioner av tall, ikke 1000-tallet. Også noen GPUer gjør det bedre med flottører, i det spesielle tilfellet bruker du flyter. Ellers, som du sier, bruk dobler.
  • @PatriciaShanahan – ‘ ytelsesproblem relatert til .. ‘ A godt eksempel er at hvis du planlegger å bruke SSE2 eller lignende vektorinstruksjoner, kan du gjøre 4 ops / vektor i flyt (vs 2 per dobbel) som kan gi en betydelig hastighetsforbedring (halvparten så mange ops og halvparten så mye data å lese & skriv). Dette kan redusere terskelen betydelig der bruk av flottør blir attraktiv, og det er verdt bryet å ordne opp de numeriske problemene.
  • Jeg støtter dette svaret med et ekstra råd: Når man opererer med RGB-verdier for visning, er akseptabelt å bruke float (og noen ganger halv presisjon) fordi verken det menneskelige øye, skjermen eller fargesystemet har så mange presisjonsbiter. Dette rådet gjelder f.eks. OpenGL osv. Dette tilleggsrådet gjelder ikke medisinske bilder som har strengere presisjonskrav.

Svar

Det er sjelden grunn til å bruke float i stedet for dobbelt i kode som er målrettet mot moderne datamaskiner. Den ekstra presisjonen reduserer (men eliminerer ikke) sjansen for avrundingsfeil eller annen upresisjon som forårsaker problemer.

Hovedårsakene til at jeg kan tenke meg å bruke float er:

  1. Du lagrer store matriser med tall og trenger å redusere programmets minneforbruk.
  2. Du målretter mot et system som ikke støtter flytende punkt med dobbel presisjon. Inntil nylig støttet mange grafikkort bare flytende punkter med presisjon. Jeg er sikker på at det er mange prosessorer med lav effekt og innebygde som også har begrenset flytpunktstøtte.
  3. Du målretter mot maskinvare der enkel presisjon er raskere enn dobbel presisjon, og applikasjonen din bruker mye bruk av flytende punkt-aritmetikk. På moderne Intel-prosessorer tror jeg alle flytende punktberegninger er gjort i dobbel presisjon, så du får ikke noe her.
  4. Du foretar optimalisering på lavt nivå, for eksempel ved å bruke spesielle CPU-instruksjoner som fungerer på flere tall om gangen.

Så, i utgangspunktet er det dobbelte å gå med mindre du har maskinvarebegrensninger eller med mindre analyse har vist at lagring av doble presisjonsnumre bidrar betydelig til minnebruk.

Kommentarer

  • » Moderne datamaskiner » som betyr Intel x86-prosessorer. Noen av maskinene Ancients brukte ga helt tilstrekkelig presisjon med den grunnleggende flottortypen. (CDC 6600 brukte et 60-biters ord, 48 biter av normalisert flytende punkt mantissa, 12 biter eksponent. At ‘ er NESTEN hva x86 gir deg for dobbelt presisjon.)
  • @ John.R.Strohm: enig, men C-kompilatorer fantes ikke på CDC6600. Det var Fortran IV …
  • Av » moderne datamaskiner » Jeg mener hvilken som helst prosessor bygget det siste tiåret eller to, eller egentlig, siden IEEE floating point-standarden ble implementert mye. Jeg ‘ er fullstendig klar over at ikke-x86-arkitekturer eksisterer og hadde det i tankene med svaret mitt – jeg nevnte GPUer og innebygde prosessorer, som vanligvis ikke er x86.
  • Det ‘ er ganske enkelt ikke sant. SSE2 kan manipulere 4 flyter eller 2 dobler i en operasjon, AVX kan manipulere 8 flyter eller 4 dobler, AVX-512 kan manipulere 16 flyter eller 8 dobler. For enhver form for høyytelsesberegning, må matematikk på flyter betraktes som dobbelt så raskt som de samme operasjonene på dobler på x86.
  • Og det ‘ s enda verre enn det, siden du kan plassere dobbelt så mange flyter i prosessorbuffer som du kan med dobler, og minnelatens er sannsynligvis den viktigste flaskehalsen i mange programmer. Det kan være bokstavelig talt en størrelsesorden raskere å holde et helt sett med flottører varme i hurtigbufferen enn å bruke dobler og ha dem til RAM.

Svar

Bruk double for alle beregningene og tempvariablene. Bruk float når du trenger å opprettholde en rekke tall – float[] (hvis presisjon er tilstrekkelig), og du har å gjøre med over titalls tusenvis av float tall.

Mange / de fleste matematiske funksjoner eller operatører konverterer / returnerer double, og du don » t vil kaste tallene tilbake til float for alle mellomliggende trinn.

F.eks. Hvis du har en inngang på 100.000 tall fra en fil eller en strøm og trenger å sorter dem, legg tallene i et float[].

Svar

Noen plattformer (ARM Cortex-M2, Cortex-M4 osv.) Støtter ikke dobbelt (Det kan alltid kontrolleres i referansehåndboken til prosessoren din. Hvis det ikke er advarsler om kompilering eller feil, betyr det ikke at koden er optimal. double kan etterlignes .). Derfor må du kanskje holde deg til int eller float .

Hvis det ikke er tilfelle, vil jeg bruke dobbel .

Du kan sjekke den berømte artikkelen av D. Goldberg («What Every Computer Scientist Should Know About Floating-Point Arithmetic»). Du bør tenke deg om to ganger før du bruker flytende regning. Det er en ganske stor sjanse for at de ikke trengs i det hele tatt i din spesielle situasjon.

http://perso.ens-lyon.fr/jean-michel.muller/goldberg.pdf

Kommentarer

  • Dette spørsmålet var allerede ganske godt besvart for et år siden …men uansett sier jeg ‘ når du ‘ bruker dobbelt på plattformer med dobbel presisjon FPU-akselerasjon, bør du bruke det på alle andre, selv om det betyr å la kompilatoren etterligne den i stedet for å dra nytte av en FPU med bare flytende punkt (merk at FPU ‘ er ‘ kreves heller ikke på alle plattformer, faktisk definerer en Cortex-M4-arkitektur dem som en valgfri funksjon [var M2 en skrivefeil?]).
  • Nøkkelen til den logikken er, mens det ‘ sant man skal være lei av flytepunktsregning, og det ‘ er mange » quirks «, tar definitivt ikke tilstedeværelsen av FPU-støtte for dobler for å bare bruke dobler i stedet for flyter. Flyter er generelt raskere enn dobler og tar mindre minne (FPU-funksjonene varierer). Bruksvolumet forhindrer at dette punktet er i for tidlig optimalisering. I likhet med at dobbel er tydeligvis overkill for mange (kanskje til og med de fleste) applikasjoner. Må elementene på denne siden virkelig ha sine relative posisjoner og størrelser beregnet til 13 desimaler?
  • Når du inkluderer en lenke til en side eller et dokument utenfor siden, kopier du relevant informasjon, eller sammendrag, fra dokumentet til svaret ditt. Koblinger utenfor nettstedet har en tendens til å forsvinne over tid.

Svar

For problemer i den virkelige verden er prøveterskelen på dataene dine er viktige når du svarer på dette spørsmålet. Tilsvarende er støygulvet også viktig. Hvis du overskrider det ene eller det andre ved å velge datatype, vil det ikke ha noen fordel ved å øke presisjonen.

De fleste samplere fra den virkelige verden er begrenset til 24-biters DAC-er. Foreslår at 32 bits presisjon på beregninger fra den virkelige verden skal være tilstrekkelig der betydningen er 24 bits presisjon.

Dobbelt presisjon koster 2x minne. Derfor kan begrensning av bruken av dobler over flyter drastisk redusere minnefotavtrykket / båndbredden til applikasjoner som kjører.

Svar

Valget av hvilken variabel som skal brukes mellom float og double, avhenger av nøyaktigheten til dataene som kreves. Hvis det kreves at et svar har ubetydelig forskjell fra det faktiske svaret, vil antall desimaler som kreves være mange, og dermed vil diktere at det dobbelte skal være i bruk. Flyte vil hugge av noen desimaler og dermed redusere nøyaktigheten.

h3> Kommentarer

  • Dette svaret legger ikke til ‘ t noe nytt i spørsmålet, og sier ikke noe om faktisk bruk.

Svar

Vanligvis bruker jeg float typen når Jeg trenger ikke mye presisjon – for eksempel for penger – som er galt, men er det jeg pleide å gjøre feil.

På den annen side bruker jeg double når jeg trenger mer presisjon, for eksempel for komplekse matematiske algoritmer.

C99-standarden sier dette:

Det er tre typer flytende punkt: flyte, dobbel og lang dobbel. Typen dobbel gir minst like mye presisjon som flyt, og typen lang dobbel gir minst like mye presisjon som dobbelt. Verdisettet av typen float er et delsett av verdisettet av typen double; settet med verdier av typen dobbelt er en delmengde av settet med verdier av typen lang dobbelt.

Jeg har aldri brukt long double, men jeg bruker ikke C / C ++ så mye. Vanligvis bruker jeg dynamisk skrevne språk som Python, der du ikke trenger å bry deg om typene.

For mer informasjon om Double vs Float , se dette spørsmålet på SO .

Kommentarer

  • Å bruke flytende punkt for alvorlige pengeberegninger er sannsynligvis en feil.
  • float er akkurat feil type for penger. Du må bruke høyest mulig presisjon.
  • @BartvanIngenSchenau Flytende poeng for penger er vanligvis ok, binært flytpunkt er ikke. For eksempel .net ‘ s Decimal er en flytende punktstype, og den er ‘ vanligvis et godt valg for pengeberegninger.
  • @ChrisF Du trenger ikke ‘ t trenger » høy presisjon » for pengene, du trenger nøyaktige verdier.
  • @SeanMcSomething – Fair point. Flyter er imidlertid fremdeles av feil type, og gitt flytende punkttyper som er tilgjengelige på de fleste språk, trenger du » høy presisjon » for å få » eksakte verdier «.

Legg igjen en kommentar

Din e-postadresse vil ikke bli publisert. Obligatoriske felt er merket med *