Ofta i min programmeringserfarenhet måste jag fatta ett beslut om jag ska använda float eller double för mitt riktiga tal. Ibland går jag för float, ibland går jag för dubbelt, men verkligen känns det mer subjektivt. Om jag skulle konfronteras för att försvara mitt beslut skulle jag antagligen inte ange sunda skäl.

När använder du float och när använder du dubbelt? Använder du alltid dubbelt, bara när minnesbegränsningar är närvarande går du för att flyta? Eller använder du alltid float såvida inte kravet på precision kräver att du använder dubbelt? Finns det några väsentliga skillnader när det gäller beräkningskomplexitet hos grundläggande aritemik mellan float och double? Vilka är för- och nackdelarna med att använda float eller double? Och har du till och med använt långa dubbla?

Kommentarer

  • I många fall vill du använda varken, utan snarare en decimal flytande eller fast punkt typ. Binära flytpunkttyper kan ’ t representerar de flesta decimaler exakt.
  • Relaterat till Vad orsakar avrundningsfel för flytande punkter ? . @CodesInChaos mitt svar där föreslår resurser som hjälper dig att göra det beslutet, det finns ingen one-size-fits-all -lösning.
  • Vad menar du exakt med ” decimaler ”. Om du behöver representera värden som 0,01 exakt (säg för pengar), är inte (binär) flytpunkt inte svaret. Om du bara menar tal som inte är heltal är flytande punkt sannolikt ok – men då är ” decimaler ” inte det bästa ordet för att beskriva vad du behöver.
  • Med tanke på (från och med idag) accepterar de flesta grafikkort flytningar över dubbelt, grafikprogrammering använder ofta enstaka precision.
  • Du don ’ har inte alltid ett val. Till exempel, på Arduino-plattformen, är både dubbel och flottör lika med att flyta. Du måste hitta ett tilläggsbibliotek för att hantera riktiga dubblar.

Svar

Standardvalet för en flytpunktstyp bör vara double. Det här är också den typ du får med flytpunktsbokstäver utan suffix eller (i C) standardfunktioner som fungerar på flytande punktnummer (t.ex. exp, sin, etc.).

float bör endast användas om du behöver arbeta på många flytande siffror (tänk in i storleksordningen tusentals eller mer) och analys av algoritmen har visat att det reducerade intervallet och noggrannheten inte utgör ett problem.

long double kan användas om du behöver mer räckvidd eller noggrannhet än double, och om det tillhandahåller detta på din målplattform.

Sammanfattningsvis float och long double bör reserveras för användning av specialisterna med double för ”varje dag”.

Kommentarer

  • Jag skulle förmodligen inte överväga att flyta för några tusen värden såvida det inte fanns ett prestandaproblem relaterat till floating point cachin g och dataöverföring. Det är vanligtvis en stor kostnad för att göra analysen för att visa att float är tillräckligt exakt.
  • Som ett tillägg kan det vara fördelaktigt att använda samma datatyper om du behöver kompatibilitet med andra system. li>
  • Jag ’ Jag använder flottör för miljontals nummer, inte 1000-tal. Vissa grafikprocessorer klarar sig också bättre med floats, i det specialiserade fallet använder floats. Annars, som du säger, använd dubbelt.
  • @PatriciaShanahan – ’ prestandaproblem relaterat till .. ’ A bra exempel är om du planerar att använda SSE2 eller liknande vektorinstruktioner, kan du göra 4 ops / vector i float (vs 2 per double) vilket kan ge en betydande hastighetsförbättring (hälften så många ops och hälften så mycket data att läsa & skriv). Detta kan avsevärt sänka tröskeln där användning av flottor blir attraktivt och värt besväret att reda ut de numeriska problemen.
  • Jag stöder detta svar med ytterligare ett råd: När man arbetar med RGB-värden för visning är acceptabelt att använda float (och ibland halvprecision) eftersom varken det mänskliga ögat, skärmen eller färgsystemet har så många bitar av precision. Detta råd gäller för exempelvis OpenGL etc. Dessa ytterligare råd gäller inte medicinska bilder som har strängare precisionskrav.

Svar

Det finns sällan anledning att använda float istället för dubbelt i kod riktad mot moderna datorer. Den extra precisionen minskar (men eliminerar inte) risken för avrundningsfel eller andra felaktigheter som orsakar problem.

De viktigaste anledningarna till att jag kan tänka mig att använda float är:

  1. Du lagrar stora siffror och behöver minska programmets minnesförbrukning.
  2. Du riktar dig mot ett system som inte stöder flytande punkt med dubbel precision. Fram till nyligen stödde många grafikkort endast enstaka flytande punkter. Jag är säker på att det finns gott om processorer med låg effekt och inbyggda enheter som också har begränsat flytande punkt.
  3. Du riktar dig mot hårdvara där enkelprecision är snabbare än dubbelprecision och din applikation använder tungt av flytande punktsaritmetik. På moderna Intel-processorer tror jag att alla flytpunktsberäkningar görs i dubbel precision, så du får inget här.
  4. Du gör optimering på låg nivå, till exempel genom att använda speciella CPU-instruktioner som fungerar på flera nummer åt gången.

Så i princip är dubbelt så att gå om du inte har maskinvarubegränsningar eller såvida inte analys har visat att lagring av dubbla precisionsnummer bidrar avsevärt till minnesanvändning.

Kommentarer

  • ” Moderna datorer ” som betyder Intel x86-processorer. Några av de maskiner som de gamla använde gav perfekt adekvat precision med den grundläggande flottörtypen. (CDC 6600 använde ett 60-bitars ord, 48 bitar normaliserad flytande mantissa, 12 bitar exponent. Det ’ är NÄSTA vad x86 ger dig för dubbel precision.)
  • @ John.R.Strohm: kom överens, men C-kompilatorer fanns inte på CDC6600. Det var Fortran IV …
  • Av ” moderna datorer ” Jag menar vilken processor som helst som byggts under det senaste decenniet eller två, eller egentligen, eftersom IEEE-standard för flytande punkter implementerades i stor utsträckning. Jag ’ är helt medveten om att det finns icke-x86-arkitekturer och hade det i åtanke med mitt svar – jag nämnde GPU: er och inbäddade processorer, som vanligtvis inte är x86.
  • Det ’ är dock helt enkelt inte sant. SSE2 kan manipulera 4 flottörer eller 2 dubblar i en operation, AVX kan manipulera 8 flottor eller 4 dubbel, AVX-512 kan manipulera 16 flottar eller 8 dubbel. För alla typer av högpresterande datorer bör matematik på flytande betraktas som dubbelt så snabbt som samma operationer på dubbelt på x86.
  • Och det ’ s ännu värre än så, eftersom du kan passa dubbelt så många flytningar i processorns cache som du kan med dubbla, och minnesfördröjning är sannolikt den viktigaste flaskhalsen i många program. Att hålla en hel fungerande uppsättning flottör varma i cache kan vara bokstavligen en storleksordning snabbare än att använda dubbla och låta dem spillas till RAM.

Svar

Använd double för alla dina beräkningar och tempvariabler. Använd float när du behöver behålla en rad med siffror – float[] (om precision är tillräcklig) och du har att göra med över tiotals tusentals float -nummer.

Många / de flesta matematiska funktioner eller operatörer konverterar / returnerar double, och du don ” t vill kasta siffrorna tillbaka till float för alla mellansteg.

Till exempel om du har en inmatning på 100 000 nummer från en fil eller en ström och behöver sortera dem, placera siffrorna i ett float[].

Svar

Vissa plattformar (ARM Cortex-M2, Cortex-M4 etc) stöder inte dubbel (Det kan alltid kontrolleras i referenshandboken till din processor. Om det inte finns några kompileringsvarningar eller fel betyder det inte att koden är optimal. dubbel kan emuleras .). Det är därför du kan behöva hålla fast vid int eller float .

Om så inte är fallet skulle jag använda dubbel .

Du kan kolla in den berömda artikeln av D. Goldberg (”Vad varje datavetenskaplig borde veta om flytpunkt-aritmetik”). Du bör tänka två gånger innan du använder flytpunktsräkning. Det finns en ganska stor chans att de inte alls behövs i din speciella situation.

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

Kommentarer

  • Den här frågan besvarades redan ganska bra för ett år sedan …men i alla fall säger jag ’ när du ’ använder dubbla på plattformar med dubbel precision FPU-acceleration, bör du använda det på alla andra, även om det innebär att låta kompilatorn emulera den istället för att dra nytta av en FPU med endast flytande punkt (notera att FPU ’ är ’ krävs inte heller på alla plattformar, i själva verket definierar en Cortex-M4-arkitektur dem som en valfri funktion [var M2 ett stavfel?]).
  • Nyckeln till den logiken är, medan det ’ sant bör man vara trött på aritmetik med flytande punkter, och det ’ s många ” quirks ”, tar definitivt inte närvaron av FPU-stöd för dubbel så att du bara använder dubbel istället för flyt. Floats är i allmänhet snabbare än dubbel och tar mindre minne (FPU-funktioner varierar). Användningsvolymen hindrar denna punkt från att vara på för tidig optimering. Liksom faktum är dubbelt klart överdrivet för många (kanske till och med de flesta) applikationer. Behöver elementen på denna sida verkligen ha sina relativa positioner och storlekar beräknade till 13 decimaler?
  • När du inkluderar en länk till en sida eller ett dokument utanför webbplatsen, kopiera relevant information, eller sammanfattning, från dokumentet till ditt svar. Länkar utanför webbplatser har en tendens att försvinna över tiden.

Svar

För verkliga problem är samplingsgränsen för dina uppgifter är viktiga när du besvarar denna fråga. På samma sätt är bullergolvet också viktigt. Om endera överskrids av ditt datatypval kommer ingen fördel att öka precisionen.

De flesta samplare i den verkliga världen är begränsade till 24-bitars DAC. Föreslår att 32 bitar av precision på beräkningar i verkliga världen ska vara tillräckliga där signifikansen är 24 bitar av precision.

Dubbel precision kostar 2x minne. Därför kan en begränsning av användningen av dubbletter över floats drastiskt minska minnesavtrycket / bandbredden för program som körs.

Svar

Valet av vilken variabel som ska användas mellan float och double beror på noggrannheten i de uppgifter som krävs. Om ett svar måste ha en försumbar skillnad från det faktiska svaret, kommer antalet decimaler som krävs att vara många, vilket kommer att diktera den dubbla för att vara i bruk. Flottan hugger av några decimaler och minskar noggrannheten.

Kommentarer

  • Det här svaret lägger inte till ’ inget nytt i frågan och kan inte säga någonting som faktiskt används.

Svar

Vanligtvis använder jag float typ när Jag behöver inte mycket precision – till exempel för pengar – vilket är fel, men det är vad jag brukade göra fel.

Å andra sidan använder jag double när jag behöver mer precision, till exempel för komplexa matematiska algoritmer.

C99-standarden säger detta:

Det finns tre typer av flytande punkter: float, double och long double. Typen dubbel ger minst lika mycket precision som flyt, och typen lång dubbel ger minst lika mycket precision som dubbel. Uppsättningen av värden för typen flyt är en delmängd av uppsättningen värden av typen dubbel; uppsättningen värden av typen dubbel är en delmängd av uppsättningen värden av typen lång dubbel.

Jag har aldrig riktigt använt long double, men jag använder inte C / C ++ så mycket. Vanligtvis använder jag dynamiskt skrivna språk som Python, där du inte behöver bry dig om typerna.

För mer information om Double vs Float , se denna fråga på SO .

Kommentarer

  • Att använda flytpunkt för allvarliga pengarberäkningar är förmodligen ett misstag.
  • float är exakt fel typ för pengar. Du måste använda högsta möjliga precision.
  • @BartvanIngenSchenau Flytpunkt för pengar är vanligtvis okej, binär flytpunkt är inte. Till exempel .net ’ s Decimal är typ av flytande punkt och det ’ är vanligtvis ett bra val för pengarberäkningar.
  • @ChrisF Du behöver ’ t behöver ” hög precision ” för pengarna, du behöver exakta värden.
  • @SeanMcSomething – Fair point. Flottor är dock fortfarande av fel typ och med tanke på de flytande punkttyperna som finns på de flesta språk behöver du ” hög precision ” för att få ” exakta värden ”.

Lämna ett svar

Din e-postadress kommer inte publiceras. Obligatoriska fält är märkta *