Учитывая число с плавающей запятой, я хочу округлить результат до 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
, Я не смог найти ничего в стандартной библиотеке, есть ли функция для достижения этой цели? Если нет, то как бы выглядела пользовательская функция?
Если вы используете 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
использует под капотом).
Я уверен, что кто-то может улучшить это, но это сделает работу.
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;
}
}