C++: Hoe rond ik een double af op een int?

Ik heb een dubbel (noem het x), bedoeld als 55, maar in werkelijkheid opgeslagen als 54,9999999999999943157, wat ik me net realiseerde.

Dus als ik dat doe

double x = 54.999999999999943157;
int y = (int) x;

y = 54 in plaats van 55!

Dit heeft me lang in verwarring gebracht. Hoe krijg ik het goed rond?


Antwoord 1, autoriteit 100%

voeg 0,5 toe voor het casten (als x > 0) of trek 0,5 af (als x < 0), omdat de compiler altijd afkapt.

float x = 55; // stored as 54.999999...
x = x + 0.5 - (x<0); // x is now 55.499999...
int y = (int)x; // truncated to 55

C++11 introduceert ook std::round, dat gebruikt waarschijnlijk een vergelijkbare logica om 0,5 toe te voegen aan |x| onder de motorkap (zie de link indien geïnteresseerd) maar is duidelijk robuuster.

Een vervolgvraag kan zijn: waaromde float niet is opgeslagen als exact 55. Voor uitleg, zie ditstackoverflow-antwoord.


Antwoord 2, autoriteit 42%

Casting is geen wiskundige bewerking en gedraagt ​​zich ook niet als zodanig. Probeer

int y = (int)round(x);

Antwoord 3, autoriteit 6%

Casten naar een intkapt de waarde af. Door 0.5toe te voegen, wordt er correct afgerond.

int y = (int)(x + 0.5);

Antwoord 4, autoriteit 3%

Het is vermeldenswaard dat wat je doet niet afronden is, maar casten. Casten met (int) xkapt de decimale waarde van xaf. Zoals in uw voorbeeld, als x = 3.9995, wordt de .9995afgekapt en x = 3.

Zoals voorgesteld door vele anderen, is een oplossing om 0.5toe te voegen aan xen vervolgens te casten.


Antwoord 5

#include <iostream>
#include <cmath>
using namespace std;
int main()
{
    double x=54.999999999999943157;
    int y=ceil(x);//The ceil() function returns the smallest integer no less than x
    return 0;
}

Other episodes