Я написал эту функцию рекурсивно круглые в double
до N цифр:C++ этаж() уменьшается значение 1
double RoundDouble(double value, unsigned int digits)
{
if (value == 0.0)
return value;
string num = dtos(value);
size_t found = num.find(".");
string dec = "";
if (found != string::npos)
dec = num.substr(found + 1);
else
return value;
if (dec.length() <= digits)
{
LogToFile("C:\\test.txt", "RETURN: " + dtos(value) + "\n\n\n");
return value;
}
else
{
double p10 = pow(10, (dec.length() - 1));
LogToFile("C:\\test.txt", "VALUE: " + dtos(value) + "\n");
double mul = value * p10;
LogToFile("C:\\test.txt", "MUL: " + dtos(mul) + "\n");
double sum = mul + 0.5;
LogToFile("C:\\test.txt", "SUM: " + dtos(sum) + "\n");
double floored = floor(sum);
LogToFile("C:\\test.txt", "FLOORED: " + dtos(floored) + "\n");
double div = floored/p10;
LogToFile("C:\\test.txt", "DIV: " + dtos(div) + "\n-------\n");
return RoundDouble(div, digits);
}
}
Но из файла журнала, то действительно странное происходит с полом() в некоторых случаях ...
Вот выходной пример хорошего расчета:
VALUE: 2.0108
MUL: 2010.8
SUM: 2011.3
FLOORED: 2011
DIV: 2.011
-------
VALUE: 2.011
MUL: 201.1
SUM: 201.6
FLOORED: 201
DIV: 2.01
-------
RETURN: 2.01
А вот выход пример плохого расчета:
VALUE: 67.6946
MUL: 67694.6
SUM: 67695.1
FLOORED: 67695
DIV: 67.695
-------
VALUE: 67.695
MUL: 6769.5
SUM: 6770
FLOORED: 6769 <= PROBLEM HERE
DIV: 67.69
-------
RETURN: 67.69
Не пол (6770) должен возвращать 6770? Почему он возвращает 6769?
Потому что это не на самом деле 6770, а нечто очень близкое к нему. [Что каждый компьютерный ученый должен знать о арифметике с плавающей точкой] (http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html) –
«Не должен быть этаж (6770) 6770?» Это неверно для небольших значений 6770. – user2079303
Попробуйте добавить значение эпсилона на пол, это похоже на то, что значение действительно 6769 с десятичными знаками, что делает его близким к 6770. –