Jeg kommer fra Java- og C # -bakgrunn og har lært å bruke int
(32 bits) når jeg trenger et helt tall, og double
(64 bits) når det gjelder brøkverdier. De fleste metoder fra deres respektive rammer (JVM og .NET) forventer vanligvis disse to typene.
Spørsmålet mitt er, hvorfor bruker vi ikke både long
og double
for konsistens? Jeg vet at det ikke er nødvendig med 64 biter presisjon i heltall, men vi trenger ikke igjen 64 biter presisjon i flytende tall, eller gjør vi det?
Hva er begrunnelsen bak dette, hvis noen?
Kommentarer
A nswer
Område vs. presisjon
En ting er at jeg vil bestride ideen om at det vanligste tallet for flytende punkt bruker en 64-biters DPFP (dobbel-presisjon flytende punkt) -representasjon.
I det minste i ytelseskritisk real- tidsfelt som spill, SPFP (flytende punkt med en presisjon) er fremdeles langt mer vanlig, siden tilnærming og hastighet der er å foretrekke fremfor ytterste nøyaktighet.
Likevel er kanskje en måte å se på dette på at en 32 -bit int
representerer et område på 2^32
heltall (~ 4,3 milliarder). Den vanligste bruken av heltall kommer sannsynligvis til å være som indekser for elementer, og at «et ganske sunt utvalg av elementer som det ville være vanskelig å overskride uten å overskride minnet som er tilgjengelig med dagens maskinvare *.
* Merk at ut av minnefeil kan oppstå når du tildeler / får tilgang til en enkelt sammenhengende 4 gigabyte blokk selv med 30 gigabyte ledig, f.eks. på grunn av sammenheng kravene til den blokken.
Et 32-biters heltall er ikke alltid mer effektivt på instruksjonsnivå, men det har en tendens til å være mer effektiv når den blir samlet i en matrise, for eksempel fordi den krever halvparten av minnet (flere indekser som kan passe inn i en enkelt side / cache-linje, f.eks.).
Vær også oppmerksom på at som Lightness Races in Orbit
påpeker, det er ikke nødvendigvis engang sant fra et bredt perspektiv at 32-biters heltall er mer vanlig. Jeg har mitt smale perspektiv som kommer fra et felt der 32-bit ints
ofte blir samlet av hundretusener til millioner som indekser i en annen struktur – der kan halveringen i størrelse hjelpe en mye.
Nå kan 64-biters DPFP brukes mye mer enn 64-biters heltall i noen sammenhenger. Der legger de ekstra bitene til presisjon i stedet for rekkevidde . Mange applikasjoner kan kreve presisjon, eller i det minste ha en mye enklere tidsprogrammering med ekstra presisjon tilgjengelig. Så det er sannsynligvis hvorfor 64-biters DPFPer kan være vanligere enn 64-biters heltall i noen områder, og hvorfor int
fremdeles kan være 32-bits i mange scenarier, selv på 64-biters plattformer.
Kommentarer
- Jeg ‘ d bestrider ideen at den vanligste integrerte datatypen også er 32 bits bred, i hvert fall i programmer som er skrevet i dag på råvare. 64-biters plattformer er så utbredte nå.
- @I Ke: Tingen er at jeg mistenker at mye programvare bare bruker
int
oglong
uten å bry meg om hva området er … og slik programvare, tror jeg, hovedsakelig bruker 64-biters heltall i begge tilfeller i dag. - Hmm jeg står korrigert; tilsynelatende er
int
generelt fortsatt 32-bit , stort sett for å unngå å innføre feil i akkurat den slags kode. Ok vel, du ‘ har fortsattsize_t
oglong
. - @ LightnessRacesinOrbit Ah forstår jeg, jeg ‘ er ekstremt partisk siden jeg ofte jobber i kodebaser som samler heltall i en eller annen datastruktur med bekymring for den totale minnestørrelsen. Jeg prøvde å gjøre svaret mitt så nøytralt som mulig.
- @I ke: Personlig lager jeg også alle typene mine eksplisitt størrelse.Men du og jeg er utvilsomt unormale. 🙂
Svar
Vel, int og double er en Java-ting. For eksempel, i Objective-C og Swift vil du bruke NSInteger eller Int, som er 32 bit på en 32 bit maskin og 64 bit på en 64 bit maskin. Stor nok til å telle et hvilket som helst antall gjenstander som kan være i minnet. Det som definitivt er nyttig, er å bruke samme type nesten overalt, med mindre du i en bestemt situasjon trenger noe annet.
Java prøver å ha koden som kjører den samme på en hvilken som helst implementering, så de mener du bør bruke samme type uavhengig av maskinen du bruker, og at typen skal ha samme antall biter uavhengig maskinen. Objective-C og Swift (og C, C ++ også) har et annet synspunkt.
Heltall brukes for det meste til å telle ting, og vanligvis har du ikke så mange ting å telle. Flytende aritmetikk trenger presisjon, og 32-biters flytpunkt gir deg ofte ikke nok presisjon. Ved å bruke 64-biters dobbel overalt, får du en kampsjanse for alltid å ha nok presisjon, uten å være spesialist i flytepunktsregning. flottør virker ikke.
Men hvilken konsistens vil du bruke lang og dobbelt? Heltall og flytende tall er ikke det samme. Det er ikke behov for at de har jevn bitstørrelse. Jeg bruker 2D-punkter og rektangler mye. Så for konsistens, burde de også være 64 bits? Poeng med 32 bit per komponent, og rektangler som har 16? Selvfølgelig ikke. Ingen konsistens nødvendig.
Kommentarer
- Dette er et veldig hyggelig svar som forklarer JVM-siden ved å holde størrelsen på hver type den samme uansett plattform.
Svar
kort, int, enkelt og dobbelt har samme størrelse i java som de er i de vanligste C-kompilatorene for 32-biters og 64-biters plattformer og C som java anser tydeligvis int som hovedtypen og dobbelt som den viktigste flytende punkttypen. Jeg synes det er rimelig å si at Java arvet denne konvensjonen fra vanlige C-kompilatorer på den tiden.
Heltall er vanligvis brukt til c unger eller indekserer ting. Det er ganske sjelden (men ikke uhørt) å trenge å telle eller indeksere mer enn 2 milliarder av noe. Før C99 måtte du faktisk bruke leverandørspesifikke typer hvis du ønsket et 64-biters heltall.
Flytende tall brukes vanligvis som en tilnærming til de reelle tallene. Enkel presisjon er god nok mye av tiden, men det er ikke vanskelig å finne problemer der det forårsaker en uakseptabel mengde avrundingsfeil. Jeg forventer at etterspørsel fra vitenskapelig databehandling er det som drev dobbel presisjon med flytende punktstøtte for å være allestedsnærværende lenge før 64-bit heltallsstøtte var.
Det jeg synes er nysgjerrig, er at C ser ut til å oppmuntre til bruk av dobbelt, mens fortran ser ut til å oppmuntre til bruk av enkelt presisjon.
BigDecimal
for flytende tall siden avrunding og å sammenligne FP-verdier er så problematisk.