Округление

Сколько будет?

  • 117559.36

    Голосов: 6 60,0%
  • 117559.37

    Голосов: 4 40,0%

  • Всего проголосовало
    10

MiksIr

miksir@home:~$
117559.36499999998
Нужно округлить до 2-х знаков после запятой.
 

MiksIr

miksir@home:~$
Дайте алгоритм как с этим жить, если мы знаем, что эти девятки - результат машинной точности?
 

Andkorol

Новичок
Использовать третий параметр функции roundmode?
PHP_ROUND_HALF_DOWN – дает математически точный результат округления, при данных условиях.
 

MiksIr

miksir@home:~$
Нет, вопрос не в том. Математически точный результат в случае _машиных_ вычислений будет 117559.37, поскольку на самом деле число то 117559.365. PHP вот отрабатывает примитивные ошибки машинной точности. А к примеру JavaScript - нет. И несмотря на то, что число 117559.365 - мы будем при округлении получать 117559.36, ибо JS округляет математическое число 117559.36499999998.
Как я понимаю, нужно 117559.36499999998 сначала как-то округлить, что бы устранить машинную ошибку, а потом уже делать свои округления. Вот в общем вопрос в алгоритме этого первого округления.
 

MiksIr

miksir@home:~$
Угу. Причем сразу в двух местах - на клиенте и на сервере. И тут бац - одна копейка разницы =) Как вариант пока передаем на сервер неокругленные данные, PHP даже пришедшее "извне" 117559.36499999998 округляет до 117559.37, что в принципе, имхо, неверно (ибо это число не результат вычисления, а пришедшее извне), но нас устраивает =)
 

MiksIr

miksir@home:~$
Там целое перемножается на сложный коэффициент. Ошибка идет уже с коэффициента. Вот я и пытаюсь "считать в копейках", только их тоже нужно округлять.
 

С.

Продвинутый новичок
Во всех бухгалтерских задачах есть четкие нормы, на каком промежуточном шаге и до скольки знаков округлять. Если им следовать, то никаких проблем с машинным представлением не будет.

Пришедшего извне числа 117559.36499999998 в такой задаче в принципе быть не может, так как даже промежуточное число требует округления до копеек или до сотых копеек согласно нормативу.
 

MiksIr

miksir@home:~$
вообще везде рекомендуют перед округлением прибавлять 0.00001
Да, возможно этот хак сработает, спасибо =) Хотя все интересно, почему 5 знаков после запятой...а не 6 =)
Вообще ЯП (тот же PHP) же делают такие округления, значит есть какие-то алгоритмы.. врядли там тупо 0.00001 прибавляется
 

Фанат

oncle terrible
Команда форума
я от балды написал, если честно.
главное, чтобы в девятки попадало
 

MiksIr

miksir@home:~$
Понятно =)))))
PHP:
$point = strpos($num, ".");
if ($point !== false) {
  $nine = strpos($num, "999", $point);
  if ($nine !== false) {
     $round = "0." . str_repeat("0", $nine-$num+1) . "1";
     $rounded_num = $num + $round;
  }
}
 

Ragazzo

TDD interested
MiksIr
В питоне есть специальный тип данных для таких вещей :D пхп же...
 

Фанат

oncle terrible
Команда форума
Я неверно выразился.
Речь о заведомо не значащей величине, но при этом попадающей в периодические девятки.
Весь этот твой наворот совершенно лишний.
Достаточно просто прибавить и округлить.
 

MiksIr

miksir@home:~$
Проблема в том, что мы не знаем "незначащую" величину и в каком месте начинаются девятки. Так что от балды выдумывать такую коррекцию не совсем верно.
 

Sender

Новичок
эм, не совсем понял в чем проблема:

на сервере юзай http://php.net/manual/en/book.bc.php на клиенте при расчетах для начала умножай все входящие данные на 100, потом округляй и дели на 100 конечную цифру

не?
 
Сверху