Вычисления с плавающей запятой - довольно забавная вещь: попробуйте следующее:
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));
и будьте вполне уверены, что все крайние случаи покрыты.