Afkomstig van een Java- en C # -achtergrond, heb ik “geleerd int
(32 bits) te gebruiken wanneer ik hebben een geheel getal nodig, en double
(64 bits) bij het omgaan met fractionele waarden. De meeste methoden van hun respectievelijke frameworks (JVM en .NET) verwachten gewoonlijk deze twee typen.
Mijn vraag is: waarom gebruiken we niet zowel long
als double
voor consistentie? Ik weet dat 64 bits precisie in gehele getallen meestal niet nodig is, maar nogmaals, we hebben meestal geen 64 bits precisie nodig in getallen met drijvende komma, of toch?
Wat is de redenering hierachter, indien van toepassing?
Reacties
A nswer
Bereik versus precisie
Eén ding is dat ik het idee zou betwisten dat het meest voorkomende drijvende-kommagetal een 64-bits DPFP-weergave (dubbele precisie drijvende-komma) gebruikt.
Ten minste in prestatie-kritische real- tijdvelden zoals games, SPFP (single-precision floating-point) komt nog steeds veel vaker voor, aangezien benadering en snelheid de voorkeur hebben boven uiterste nauwkeurigheid.
Maar misschien is een manier om hiernaar te kijken, dat een 32 -bit int
vertegenwoordigt een bereik van 2^32
gehele getallen (~ 4,3 miljard). Het meest voorkomende gebruik van gehele getallen zal waarschijnlijk zijn als indices voor elementen, en dat “is een behoorlijk gezonde reeks elementen die moeilijk te overschrijden zijn zonder het beschikbare geheugen te overschrijden met de huidige hardware *.
* Houd er rekening mee dat er onvoldoende geheugenfouten kunnen optreden bij het toewijzen / openen van een enkel aaneengesloten blok van 4 gigabyte, zelfs met 30 gigabyte vrij, bijvoorbeeld vanwege de aangrenzende vereisten van dat blok.
Een 32-bits geheel getal is niet altijd efficiënter op instructieniveau, maar is over het algemeen efficiënter wanneer het wordt geaggregeerd in een array, bijvoorbeeld omdat het de helft van het geheugen vereist (meer indices die in een enkele pagina / cache-regel passen, bijvoorbeeld).
Merk ook op dat als Lightness Races in Orbit
wijst erop dat het niet noodzakelijkerwijs eens waar is vanuit een breed perspectief dat 32-bits gehele getallen vaker worden gebruikt. Mijn enge perspectief komt uit een veld waarin 32-bits ints
vaak worden samengevoegd door honderdduizenden tot miljoenen als indices in een andere structuur – daar kan de halvering in grootte een veel.
Nu kan 64-bits DPFP in sommige contexten veel meer dan 64-bits gehele getallen worden gebruikt. Daar voegen de extra bits precisie toe in plaats van bereik . Veel toepassingen vereisen precisie, of hebben in ieder geval een veel eenvoudigere tijdprogrammering met extra precisie. Dus dat is waarschijnlijk de reden waarom 64-bits DPFPs mogelijk vaker voorkomen dan 64-bits gehele getallen in sommige gebieden, en waarom int
nog steeds 32-bits kan zijn in veel scenarios, zelfs op 64-bits platforms.
Reacties
- Ik ‘ d betwist het idee dat het meest voorkomende integrale gegevenstype ook 32 bits breed is, in ieder geval in programmas die tegenwoordig op standaardhardware zijn geschreven. 64-bits platforms zijn nu zo wijdverspreid.
- @I Ke: Ik vermoed dat veel software alleen
int
enlong
gebruikt zonder echt te kunnen schelen wat het bereik is … en dergelijke software gebruikt, denk ik, tegenwoordig voornamelijk 64-bits gehele getallen in beide gevallen. - Hmm ik sta gecorrigeerd; blijkbaar is
int
over het algemeen nog steeds 32-bits , grotendeels om het introduceren van bugs in precies dat soort code te voorkomen. Oké, je ‘ hebt nog steedssize_t
enlong
. - @LightnessRacesinOrbit Ah, ik begrijp het, ik ‘ ben extreem bevooroordeeld omdat ik vaak werk in codebases die gehele getallen samenvoegen in een datastructuur met bezorgdheid over de totale geheugengrootte. Ik heb geprobeerd mijn antwoord zo neutraal mogelijk te maken.
- @Ik: Persoonlijk maak ik al mijn typen ook expliciet op maat.Maar jij en ik zijn ongetwijfeld abnormaal. 🙂
Answer
Nou, int en double is iets van Java. In Objective-C en Swift zou je bijvoorbeeld NSInteger of Int gebruiken, wat 32 bit is op een 32 bit machine en 64 bit op een 64 bit machine. Groot genoeg om een willekeurig aantal items in het geheugen te tellen. Wat zeker handig is, is om bijna overal hetzelfde type te gebruiken, tenzij je in een bepaalde situatie iets anders nodig hebt.
Java probeert code te hebben die op elke implementatie hetzelfde draait, dus denken ze dat je hetzelfde type moet gebruiken, onafhankelijk van de machine die je gebruikt, en dat het type hetzelfde aantal bits moet hebben, onafhankelijk van het apparaat. Objective-C en Swift (en ook C, C ++) hebben een ander standpunt.
Gehele getallen worden meestal gebruikt voor het tellen van dingen, en meestal hoef je niet zoveel dingen te tellen. Drijvende-kommaberekeningen hebben precisie nodig, en 32-bits drijvende-komma geeft je vaak niet genoeg precisie. Door overal 64 bit dubbel te gebruiken, heb je de kans om altijd voldoende precisie te hebben, zonder een specialist te zijn in drijvende-kommaberekeningen. float doet het niet.
Maar welke consistentie zou het gebruik van long en double je opleveren? Gehele getallen en getallen met drijvende komma zijn niet hetzelfde. Het is niet nodig dat ze een consistente bitgrootte hebben. Ik gebruik 2D-punten en rechthoeken veel. Dus voor consistentie, zouden ze ook 64 bits moeten zijn? Punten met 32 bits per component en rechthoeken met 16? Natuurlijk niet. Geen consistentie nodig.
Opmerkingen
- Dit is een heel mooi antwoord dat de JVM-kant ervan uitlegt om de grootte van elk type hetzelfde te houden, ongeacht het platform.
Antwoord
short, int, single en double hebben dezelfde grootte in java als in de meest voorkomende C-compilers voor 32-bit en 64-bit platforms en C zoals java beschouwt int duidelijk als het belangrijkste integer-type en double als het belangrijkste drijvende-kommatype. Ik denk dat het redelijk is om te zeggen dat Java deze conventie destijds van gewone C-compilers heeft geërfd.
Gehele getallen zijn meestal gebruikt voor c Dingen tellen of indexeren. Het is vrij zeldzaam (hoewel niet ongehoord) om meer dan 2 miljard van iets te tellen of te indexeren. Vóór C99 moest u inderdaad leverancierspecifieke typen gebruiken als u een 64-bits geheel getal wilde.
Drijvende-kommagetallen worden meestal gebruikt als een benadering van de reële getallen. Enkele precisie is vaak goed genoeg, maar het is niet moeilijk om problemen te vinden waarbij het een onaanvaardbare hoeveelheid afrondingsfouten veroorzaakt. Ik verwacht dat de vraag van wetenschappelijk computergebruik ertoe heeft geleid dat ondersteuning voor drijvende-komma met dubbele precisie alomtegenwoordig is lang vóór 64-bits integer-ondersteuning was.
Wat ik wel merkwaardig vind, is dat C het gebruik van double lijkt aan te moedigen, terwijl fortran het gebruik van enkele precisie lijkt aan te moedigen.
BigDecimal
te gebruiken voor getallen met drijvende komma, sinds het afronden en het vergelijken van FP-waarden is zo problematisch.