Moet ik double of float gebruiken?

Wat zijn de voor- en nadelen van het gebruik van de ene in plaats van de andere in C++?


Antwoord 1, autoriteit 100%

Als je het echte antwoord wilt weten, lees dan Wat elke computerwetenschapper moet weten over rekenkunde met drijvende komma.

Kortom, hoewel doublehogere precisietoelaat in zijn representatie, zou het voor bepaalde berekeningen grotere foutenopleveren. De “juiste” keuze is: gebruik zoveel precisie als je nodig hebt, maar niet meeren kies het juiste algoritme.

Veel compilers doen sowieso uitgebreide drijvende-komma-berekeningen in “niet-strikte” modus (d.w.z. gebruiken een breder type drijvende-komma dat beschikbaar is in hardware, bijvoorbeeld 80-bits en 128-bits zwevend), hiermee moet ook rekening worden gehouden. In de praktijk zie je nauwelijks verschil in snelheid— ze zijn sowieso van nature in hardware.


Antwoord 2, autoriteit 44%

Tenzij je een specifieke reden hebt om het anders te doen, gebruik dubbel.

Misschien verrassend genoeg is het double en niet float, het “normale” floating-point type in C (en C++). De standaard wiskundige functies zoals sinen lognemen doubles als argumenten, en return doubles. Een normale letterlijke drijvende komma, zoals wanneer u 3.14in uw programma schrijft, heeft het type double. Niet zweven.

Op typische moderne computers kunnen doubles net zo snel zijn als floats, of zelfs sneller, dus prestaties zijn meestal geen factor om te overwegen, zelfs niet voor grote berekeningen. (En dat zouden groteberekeningen moeten zijn, anders zouden prestaties niet eens in je hoofd moeten komen. Mijn nieuwe i7-desktopcomputer kan zes miljard vermenigvuldigingen van verdubbelingen in één seconde uitvoeren.)


Antwoord 3, autoriteit 24%

Deze vraag kan niet worden beantwoord omdat er geen context voor de vraag is. Hier zijn enkele dingen die de keuze kunnen beïnvloeden:

  1. Compilerimplementatie van floats, doubles en long doubles. De C++-standaard stelt:

    Er zijn drie typen drijvende komma: zwevend, dubbel en lang dubbel. Het type double geeft minstens evenveel precisie als float, en het type long double geeft minstens evenveel precisie als double.

    Dus ze kunnen alle drie even groot zijn in het geheugen.

  2. Aanwezigheid van een FPU. Niet alle CPU’s hebben FPU’s en soms worden de drijvende-kommatypen geëmuleerd en soms worden de drijvende-kommatypen gewoon niet ondersteund.

  3. FPU-architectuur. De FPU van de IA32 is intern 80-bits – 32-bits en 64-bits floats worden bij belasting uitgebreid tot 80-bits en bij opslag verminderd. Er is ook een SIMD die vier 32-bits floats of twee 64-bits floats parallel kan uitvoeren. Het gebruik van SIMD is niet gedefinieerd in de standaard, dus er zou een compiler nodig zijn die complexere analyses uitvoert om te bepalen of SIMD kan worden gebruikt, of het gebruik van speciale functies (bibliotheken of intrinsieke inhoud) vereist. Het resultaat van het interne 80bit-formaat is dat u enigszins verschillende resultaten kunt krijgen, afhankelijk van hoe vaak de gegevens in het RAM worden opgeslagen (en dus precisie verliezen). Om deze reden optimaliseren compilers de drijvende-kommacode niet bijzonder goed.

  4. Geheugenbandbreedte. Als een double meer opslagruimte nodig heeft dan een float, dan duurt het lezen van de gegevens langer. Dat is het naïeve antwoord. Op een moderne IA32 hangt het allemaal af van waar de gegevens vandaan komen. Als het zich in de L1-cache bevindt, is de belasting verwaarloosbaar, op voorwaarde dat de gegevens afkomstig zijn van een enkele cacheregel. Als het meer dan één cacheregel beslaat, is er een kleine overhead. Als het van L2 is, duurt het een tijdje langer, als het in het RAM-geheugen zit, is het nog langer en ten slotte, als het op schijf staat, is het een enorme tijd. Dus de keuze voor float of double is minder belangrijk dan de manier waarop de gegevens worden gebruikt. Als u een kleine berekening wilt maken met veel opeenvolgende gegevens, heeft een klein gegevenstype de voorkeur. Als u veel rekenwerk doet met een kleine gegevensset, kunt u grotere gegevenstypen gebruiken met enig significant effect. Als u de gegevens heel willekeurig opent, is de keuze van de gegevensgrootte onbelangrijk – gegevens worden geladen in pagina’s / cacheregels. Dus zelfs als je alleen een byte uit RAM wilt, kun je 32 bytes overzetten (dit is erg afhankelijk van de architectuur van het systeem). Bovendien zou de CPU/FPU superscalair kunnen zijn (ook wel pijplijn genoemd). Dus ook al kan het laden meerdere cycli duren, de CPU/FPU kan bezig zijn met iets anders (een vermenigvuldiging bijvoorbeeld) waardoor de laadtijd tot op zekere hoogte wordt verborgen.

  5. De standaard legt geen bepaald formaat op voor drijvende-kommawaarden.

Als u een specificatie heeft, zal die u naar de optimale keuze leiden. Anders is het een kwestie van ervaren wat je moet gebruiken.


Antwoord 4, autoriteit 15%

Double is nauwkeuriger, maar is gecodeerd op 8 bytes. float is slechts 4 bytes, dus minder ruimte en minder precisie.

Je moet heel voorzichtig zijn als je double en float in je applicatie hebt. Ik heb daardoor in het verleden een storing gehad. Een deel van de code gebruikte float terwijl de rest van de code double gebruikte. Dubbel kopiëren om te zweven en vervolgens zweven naar dubbel kan precisiefouten veroorzaken die grote gevolgen kunnen hebben. In mijn geval was het een chemische fabriek… hopelijk had het geen dramatische gevolgen 🙂

Ik denk dat het door dit soort bug is dat de Ariane 6-raket een paar jaar geleden is geëxplodeerd!!!

Denk goed na over het type dat voor een variabele moet worden gebruikt


Antwoord 5, autoriteit 5%

Persoonlijk ga ik altijd voor het dubbele totdat ik wat knelpunten zie. Dan overweeg ik om te gaan floaten of een ander onderdeel te optimaliseren


Antwoord 6, autoriteit 4%

Dit hangt af van hoe de compiler dubbel implementeert. Het is legaal dat double en float van hetzelfde type zijn (en op sommige systemen is dat ook zo).

Dat gezegd hebbende, als ze inderdaad verschillend zijn, is precisie het belangrijkste probleem. Een dubbel heeft een veel hogere precisie vanwege het verschil in grootte. Als de getallen die u gebruikt gewoonlijk de waarde van een float overschrijden, gebruik dan een double.

Verschillende andere mensen hebben prestatieproblemen genoemd. Dat zou precies de laatste zijn op mijn lijstje van overwegingen. Correctheid zou uw #1 overweging moeten zijn.


Antwoord 7, autoriteit 3%

Gebruik de vereiste precisie om de juiste resultaten te verkrijgen. Als je dan merkt dat je code niet zo goed presteert als je zou willen (heb je de juiste profilering gebruikt?) kijk dan eens naar:


Antwoord 8, autoriteit 2%

Ik denk dat, ongeacht de verschillen (die zoals iedereen aangeeft, floats minder ruimte innemen en over het algemeen sneller zijn)… heeft iemand ooit prestatieproblemen gehad met het gebruik van double? Ik zeg gebruik dubbel… en als je later besluit “wow, dit is echt traag”… zoek dan je prestatie-bottleneck (wat waarschijnlijk niet het feit is dat je dubbel hebt gebruikt). DAN, als het nog steeds te traag voor je is, kijk dan waar je wat precisie kunt opofferen en gebruik float.


Antwoord 9

double heeft een hogere precisie, terwijl floats minder geheugen in beslag nemen en sneller zijn. Over het algemeen moet je float gebruiken, tenzij je een geval hebt waarin het niet nauwkeurig genoeg is.


Antwoord 10

Het belangrijkste verschil tussen float en double is precisie. Wikipedia heeft meer informatie over
Enkele precisie(zwevend) en Dubbele precisie.


Antwoord 11

Het hangt sterk af van de CPU. De meest voor de hand liggende compromissen zijn tussen precisie en geheugen. Met GB’s RAM is geheugen niet zo’n probleem, dus het is over het algemeen beter om doubles te gebruiken.

De prestaties zijn sterk afhankelijk van de CPU. floats zullen doorgaans betere prestaties leveren dan doubles op een 32-bits machine. Op 64 bit zijn doubles soms sneller, omdat het (meestal) de oorspronkelijke grootte is. Maar wat veel belangrijker is dan uw keuze van gegevenstypen, is of u al dan niet kunt profiteren van SIMD-instructies op uw processor.

Other episodes