shmali
11.01.2013 - 18:47
На работе наткнулся на такую штуку :
Система оплаты принимает сумму типа инт . Цены на сайте типа Флоут.
Саму проблему решил , но загадка осталась . Приведу ниже код , может кто знает в чем прикол .
$total_price = 126.95;
$payment = 0;
$delivery = 8;
$summ = (($total_price + $payment + $delivery)*100);
var_dump($summ, intval($summ));die;
Вывод:
float 134.95
int 13494
Куда пропадает единица после приведения к Инту ?
Игорь_Vasinsky
11.01.2013 - 19:01
какая единица?
всё верно считает.
_____________
HTML, CSS (Bootstrap), JS(JQuery, ExtJS), PHP, MySQL, MSSql, Posgres, (TSql, BI OLAP, MDX), Mongo, Git, SVN, CodeIgnater, Symfony, Yii 2, JiRA, Redmine, Bitbucket, Composer, Rabbit MQ, Amazon (SQS, S3, Transcribe), Docker
shmali
11.01.2013 - 19:35
Цитата |
какая единица?
всё верно считает. |
Нет
134.95 * 100 = 13495
а не
13494
Скорее всего это так как описано в
Просто что смутило , что цифра довольно небольшая и та погрешность которая указана в доке , в теории не должна была так влиять.
Размер числа с плавающей точкой зависит от платформы, хотя максимум, как правило составляет ~1.8e308 с точностью около 14 десятичных цифр (64-битный IEEE формат).
с точностью около 14 десятичных
По сути получается
(float) 13495 = (int)13494 (Это результат перевода из Флоута в инт, не равенство или присваивание )
inpost
11.01.2013 - 19:39
shmaliОкруглять надо, а не приводить к int , как выше заметили.
Погрешность даже в десятичных, на JS недавно сталкивался, 0,9+0,1=0,9999 , хотя с другой стороны откуда взяться такой погрешности, ведь ни деления, ни умножения нет.
killer8080Зачем такую глупость сделали? Когда говорим о валютах, ты бы хранил валюты в копейках? 5000 копеек, вместо (float) 50 рублей ?
_____________
Обучаю веб-программированию качественно и не дорого:
http://school-php.comФрилансер, принимаю заказы: PHP, JS, AS (видео-чаты). Писать в ЛС (Личные сообщения на phpforum).
shmali
11.01.2013 - 19:45
Цитата |
Округлять надо, а не приводить к int , как выше заметили. Погрешность даже в десятичных, на JS недавно сталкивался, 0,9+0,1=0,9999 , хотя с другой стороны откуда взяться такой погрешности, ведь ни деления, ни умножения нет. |
Именно так я и решил эту проблему , но сам вопрос не пропал )))
Залез в тот самый док посмотрел погрешность и не сходится у меня , вопрос не в надежности или правильности , вопрос в том что погрешность не статична получается .. Каждый раз может бить по числам разной длинны .
Цитата |
Зачем такую глупость сделали? Когда говорим о валютах, ты бы хранил валюты в копейках? 5000 копеек, вместо (float) 50 рублей ? |
хз , на проекте несколько систем оплаты (Worldpay, Concardis) -> обе принимают денежку в таком формате.
inpost
11.01.2013 - 19:46
shmaliВозможно принимают значение и далее округляют, до 2-х чисел после запятой при округлении проблем не должно быть.
_____________
Обучаю веб-программированию качественно и не дорого:
http://school-php.comФрилансер, принимаю заказы: PHP, JS, AS (видео-чаты). Писать в ЛС (Личные сообщения на phpforum).
killer8080
12.01.2013 - 02:50
Цитата (inpost @ 11.01.2013 - 17:39) |
killer8080 Зачем такую глупость сделали? |
Что именно? Погрешность при преобразовании типов? Так это не проблема PHP, такова специфика работы ЦПУ.
Цитата (inpost @ 11.01.2013 - 17:39) |
Когда говорим о валютах, ты бы хранил валюты в копейках? 5000 копеек, вместо (float) 50 рублей ? |
Это все равно бы не спасло, те же официальные курсы валют, у них больше двух знаков после запятой, так что без FPU, тут не обойтись.