Стандартная библиотека имеет функцию fmod
для модуля с плавающей запятой (remainder
не так полезна, поскольку не гарантирует тот же знак, что и операнд числителя).
Однако вы должны учитывать, что 0.05
не представимо в двоичной переменной с плавающей точкой.Следовательно, значение «кратный 0,05» в реальной математике принципиально отличается от значения «кратного значения с плавающей запятой, которое является ближайшим представимым значением к 0,05».
Учитывая, что входные данные вычислениясодержит некоторую ошибку, эта ошибка будет увеличиваться при операциях с плавающей запятой на этих входах.Вполне возможно, что даже если 0,05 * x = y верно в реальной математике, это не обязательно означает, что это верно в математике с плавающей запятой.
Таким образом, редко имеет смысл сравнивать результаты вычислений с плавающей запятойс одним значением.Это справедливо для сравнения остатка с нулем.Имеет смысл сравнить некоторый относительный порог, который предполагается больше, чем накопленная ошибка расчета.Поскольку вы, вероятно, имеете дело с квантованными значениями вплоть до одной сотой (как это обычно бывает с валютой), разумный порог составляет половину разрешения квантования.
double quantum = 0.01;
double threshold = quantum / 2;
bool is_multiple = std::fmod(price, 0.05) < threshold;