double Money::rounding(int convert, Currency m)
{
int tmp;
if ( (convert % m) > (m / 2.0)) {
tmp = convert + (m - (convert % m));
} else {
tmp = convert - (convert % m);
}
return convert / 100.0; // error happens here as well, 945 becomes 9.44
}
Money round(const Money target, Currency m)
{
int tmp;
double rounded;
if (target.amount < 0) {
tmp = -(target.amount * 100);
rounded = -Money::rounding(tmp, m);
} else {
tmp = target.amount * 100;
//error happens here
std::cout << tmp << std::endl; // ouput 944, should be 945
rounded = Money::rounding(tmp, m);
}
Money newM {0, 0};
newM.setAmount(rounded);
return newM;
}
int main(int argc, const char * argv[])
{
Money a {9, 45}; // equal 9.45
Money b = round(a, Currency::NICKLE); //argument a is 9.45
cout << b << endl;
}
функция состоит в том, чтобы округлить целевой экземпляр Money до ближайшей валюты, в данном случае NICKLE. поскольку Money a составляет 9,45, он должен округлить до 9,45. Но есть проблема в умножении до округления, tmp = target.amount * 100; <- становится 944, но это должно быть 945, я понимаю, что ошибки округления происходят когда-то, но это умножается на 100, почему существует ошибка округления?
При rounding
функции вы определяете tmp
но затем не используете его.
Должно быть
return tmp / 100.0;
this is only multiplied by 100, why there is a rounding error
поскольку числа с плавающей запятой представлены в базе 2, а не в базе 10 (поэтому, следовательно, 100 не является чем-то особенным). 45/100 не является точно представимым в базе 2 по той же причине, что 1/3 не является точно представимым в базе 10, как конечная десятичная дробь.