Ошибка округления умножения

0
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, почему существует ошибка округления?

  • 0
    Это еще один пример того, почему вы не должны использовать двойные числа для представления денег.
  • 2
    this is only multiplied by 100, why there is a rounding error поскольку числа с плавающей запятой представлены в базе 2, а не в базе 10 (поэтому, следовательно, 100 не является чем-то особенным). 45/100 не является точно представимым в базе 2 по той же причине, что 1/3 не является точно представимым в базе 10, как конечная десятичная дробь.
Показать ещё 1 комментарий
Теги:
rounding

1 ответ

0

При rounding функции вы определяете tmp но затем не используете его.

Должно быть

return tmp / 100.0;

Ещё вопросы

Сообщество Overcoder
Наверх
Меню