Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
PHP 5. На примерах. Авторы: Кузнецов М.В., Симдянов И.В., Голышев С.В. MySQL 5. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В. PHP на примерах (2 издание). Авторы: Кузнецов М.В., Симдянов И.В. Самоучитель PHP 5 / 6 (3 издание). Авторы: Кузнецов М.В., Симдянов И.В. PHP 5/6. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Разное

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Расчет точности числа
 
 автор: Владимир55   (23.02.2013 в 12:13)   письмо автору
 
 

Цена товара, если исчислять ее в копейках, может быть выражена целым числом. Например, 300000011 – три миллиона рублей одиннадцать копеек (9 знаков). Однако, в нашем случае эта цена включает в себя наценку или скидку, например наценку 1.17% (два знака после запятой). Таким образом, реальная цена, без наценки, будет составлять 300000011 / (1 + 0.0117) = 296530602.945537215.

Какое поле нужно предусмотреть в базе данных для записи вычисляемой таким образом цены без наценки?

(Цена товара (с наценкой) в копейках – 9 знаков. Наценка/скидка в процентах – два знака после запятой. При этом умножение вычисленной цены без наценки на наценку должно давать цену с наценкой с точностью до копейки).

  Ответить  
 
 автор: cheops   (24.02.2013 в 10:58)   письмо автору
 
   для: Владимир55   (23.02.2013 в 12:13)
 

>300000011 – три миллиона рублей одиннадцать копеек (9 знаков)
Традиционно используется запись 3000000.11. Вам конечно виднее на месте, но лучше все-таки отказаться от формата 300000011 - в конечном итоге будет проще сопровождать программу.

Обычно в банковской сфере используют 4 знака после запятой, т.е. до сотой доли копейки. А в базах данных используют тип DECIMAL с 4 знаками после запятой, например, DECIMAL(11,4). DECIMAL хранит числа в виде строки, а не виде бинарной последовательности, как FLOAT - это решает проблемы с накоплением ошибок вычислений и представлений дробей в бинарном формате.

  Ответить  
 
 автор: Владимир55   (24.02.2013 в 13:44)   письмо автору
 
   для: cheops   (24.02.2013 в 10:58)
 

От FLOAT я почти сразу отказался - даже удивительно, как сильно искажаются результаты вычислений!

Интересно, а что будет, если числа хранить в базе с полями CHAR ?

  Ответить  
 
 автор: cheops   (24.02.2013 в 18:23)   письмо автору
 
   для: Владимир55   (24.02.2013 в 13:44)
 

Ничего хорошего, для расчета потребуется приводить в FLOAT, будут те же самые ошибки. Лучше использовать DECIMAL - это тот же CHAR, только все расчеты ведутся в обход FLOAT и вообще блока сопроцессора для работы с плавающей точкой, как в пакетах символьных вычислений. Поэтому точность очень велика, хотя скорость расчета в разы меньше, чем в случае FLOAT (впрочем в случае денег, лучше медленнее, но более верно).

  Ответить  
 
 автор: Владимир55   (25.02.2013 в 11:49)   письмо автору
 
   для: cheops   (24.02.2013 в 18:23)
 

Сколько то лет тому назад я пытался сделать скрипт лунного календаря. Не получилось. Формулы, вроде бы, все верные (консультировался на сайте астрономов), а выдавалась полная ерунда.

Теперь я понимаю причину: циклическое исполнение операций с числами в формате FLOAT приводило к тому, что вычисления превратились в генерацию случайных чисел…

  Ответить  
 
 автор: cheops   (25.02.2013 в 23:17)   письмо автору
 
   для: Владимир55   (25.02.2013 в 11:49)
 

Это привет из 70-х, компьютеры изначально задумывались для научных и инженерных расчетов, где требовались одновременно и сверхмалые и сверхбольшие числа, поэтому в 8-10 байт упаковывают 10е+308 и 10е-308, да еще и с мантиссой. В качестве расплаты, не все дроби могут быть представлены, многие дроби (а речь не только о периодических) изначально заложены с ошибкой, которая отбрасывается. Зато число получается очень компактно представлено, расчеты с ним выполняются исключительно быстро 4 байта - это один 32 бита, 8 байт - это 64 бита. Современные процессоры расправляются с ними исключительно хорошо. Если продумать алгоритмы, то точность будет высокой. Но вообще, на float свет клином не сошелся... да и для ряда задач этого размера не достаточно... например, ряд целых чисел, вроде чисел Фиббоначи нужно вычислять точно, приближенно не катит и мантиссы у целого числа нет.

В PHP для этого даже специальное расширение есть http://php.net/manual/ru/ref.bc.php, в таких случаях можно задействовать его - будет медленнее, но очень точно.

  Ответить  
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования