c ++ половина округляется до x цифр

Учитывая число с плавающей запятой, я хочу округлить результат до 4 десятичных разрядов, используя округление до половины четности, т.е. округление до следующего метода четных чисел. Например, когда у меня есть следующий фрагмент кода:

#include <iostream>
#include <iomanip>

int main(){
float x = 70.04535;
std::cout << std::fixed << std::setprecision(4) << x << std::endl;
}

Выход 70.0453, но я хочу быть 70.0454, Я не смог найти ничего в стандартной библиотеке, есть ли функция для достижения этой цели? Если нет, то как бы выглядела пользовательская функция?

1

Решение

Если вы используете floatты вроде как облажался Там нет такого значения, как 70.04535потому что он не представлен в двоичной переменной с плавающей точкой IEEE 754.

Простая демонстрация с помощью Python decimal.Decimal класс, который будет пытаться воспроизвести фактический float (ну, Питон float это С double, но это тот же принцип) значение до 30 цифр точности:

>>> import decimal
>>> decimal.Decimal(70.04535)
Decimal('70.0453499999999991132426657713949680328369140625')

Таким образом, ваше действительное значение не заканчивается на 5, оно заканчивается на 49999 … (ближайший к 70.04535 C double может получить; С float еще менее точно); даже округление банкира округлило бы это. Если это важно для вашей программы, вам нужно использовать эквивалентную библиотеку C или C ++, которая соответствует математическим ожиданиям человека (base-10), например, libmpdec (это то, что Python decimal.Decimal использует под капотом).

2

Другие решения

Я уверен, что кто-то может улучшить это, но это сделает работу.

double round_p( double x, int p ){
double d = std::pow(10,p+1);
return ((x*d)+5)/d;
}
void main(int argc, const char**argv){
double x = 70.04535;
{
std::cout << "value " << x << " rounded " << round_p(x,4) << std::endl;
std::cout << "CHECK " << (bool)(round_p(x,4) == 70.0454) << std::endl;
}
}
0