[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: Загадка Float -> Int
shmali
На работе наткнулся на такую штуку :
Система оплаты принимает сумму типа инт . Цены на сайте типа Флоут.
Саму проблему решил , но загадка осталась . Приведу ниже код , может кто знает в чем прикол .


$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
какая единица?

всё верно считает.

_____________
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
killer8080
Цитата (shmali @ 11.01.2013 - 16:47)
Куда пропадает единица после приведения к Инту ?
shmali
Цитата
какая единица?

всё верно считает.


Нет

134.95 * 100 = 13495


а не
 13494


Скорее всего это так как описано в
Цитата
читай
http://php.net/manual/ru/language.types.fl...float-precision


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


Размер числа с плавающей точкой зависит от платформы, хотя максимум, как правило составляет ~1.8e308 с точностью около 14 десятичных цифр (64-битный IEEE формат).

с точностью около 14 десятичных


По сути получается
 
(float) 13495 = (int)13494 (Это результат перевода из Флоута в инт, не равенство или присваивание )
inpost
shmali
Округлять надо, а не приводить к int , как выше заметили.
Погрешность даже в десятичных, на JS недавно сталкивался, 0,9+0,1=0,9999 , хотя с другой стороны откуда взяться такой погрешности, ведь ни деления, ни умножения нет.

killer8080
Зачем такую глупость сделали? Когда говорим о валютах, ты бы хранил валюты в копейках? 5000 копеек, вместо (float) 50 рублей ?

_____________
Обучаю веб-программированию качественно и не дорого: http://school-php.com
Фрилансер, принимаю заказы: PHP, JS, AS (видео-чаты). Писать в ЛС (Личные сообщения на phpforum).
shmali
Цитата
Округлять надо, а не приводить к int , как выше заметили.
Погрешность даже в десятичных, на JS недавно сталкивался, 0,9+0,1=0,9999 , хотя с другой стороны откуда взяться такой погрешности, ведь ни деления, ни умножения нет.


Именно так я и решил эту проблему , но сам вопрос не пропал )))
Залез в тот самый док посмотрел погрешность и не сходится у меня , вопрос не в надежности или правильности , вопрос в том что погрешность не статична получается .. Каждый раз может бить по числам разной длинны .

Цитата
Зачем такую глупость сделали? Когда говорим о валютах, ты бы хранил валюты в копейках? 5000 копеек, вместо (float) 50 рублей ?


хз , на проекте несколько систем оплаты (Worldpay, Concardis) -> обе принимают денежку в таком формате.
inpost
shmali
Возможно принимают значение и далее округляют, до 2-х чисел после запятой при округлении проблем не должно быть.

_____________
Обучаю веб-программированию качественно и не дорого: http://school-php.com
Фрилансер, принимаю заказы: PHP, JS, AS (видео-чаты). Писать в ЛС (Личные сообщения на phpforum).
killer8080
Цитата (inpost @ 11.01.2013 - 17:39)
killer8080
Зачем такую глупость сделали?

Что именно? Погрешность при преобразовании типов? Так это не проблема PHP, такова специфика работы ЦПУ.
Цитата (inpost @ 11.01.2013 - 17:39)
Когда говорим о валютах, ты бы хранил валюты в копейках? 5000 копеек, вместо (float) 50 рублей ?

Это все равно бы не спасло, те же официальные курсы валют, у них больше двух знаков после запятой, так что без FPU, тут не обойтись.
Быстрый ответ:

 Графические смайлики |  Показывать подпись
Здесь расположена полная версия этой страницы.
Invision Power Board © 2001-2024 Invision Power Services, Inc.