Вычисления с плавающей точкой довольно забавная вещь: Попробуйте это:
SELECT FLOOR(38774/184*126*23+0.5);
SELECT FLOOR(38774*126*23/184+0.5);
SELECT FLOOR(ROUND(38774/184*126*23+0.5, 3));
Что тут происходит?
Наиболее важной частью является то, что 38774/184 не имеет точного представления в виде числа с плавающей запятой - вы всегда и немного меньше. С остальными вычислениями, составляющими ровно 610691, вы в итоге чуть-чуть не дотянете до 610691, что приведет FLOOR 610690.
Вторая строка избегает этого, перегруппировывая части вычисления в последовательность, которая имеет точное представление в виде числа с плавающей запятой.
Третья строка использует ROUND отрезать очень маленькую разницу, тем самым делая FLOOR работать как положено.
Практическое правило. Числа с плавающей точкой не дают точных результатов. Хотя они чаще всего являются «достаточно точными», существуют крайние случаи, когда это не так. Вы просто нажали один, и довольно обычный: преобразование обратно в целое число через FLOOR или же CEIL,
Теперь, чтобы ответить на ваш вопрос: из опыта я бы приказал вычислить так, как это делает 2-я строка - большие числа (в диапазоне INT32) с большей вероятностью приведут к правильному FLOOR, Если вычислительная стоимость приемлема для вас, я бы пошел на
SELECT FLOOR(ROUND(38774*126*23/184+0.5, 3));
и будьте вполне уверены, что все крайние случаи покрыты.
ROUNDповлиять на это? Мой подход был похожFLOOR(x*100+0.5)/100, Так что в вашем примере сROUNDследующее округлено «неправильно»:FLOOR(ROUND(4.994999999*100+0.5,3))/100=5.00вместо4.99