X   Сообщение сайта
(Сообщение закроется через 3 секунды)



 

Здравствуйте, гость (

| Вход | Регистрация )

2 страниц V   1 2 >
Открыть тему
Тема закрыта
> Копейки
Arks
Arks
Topic Starter сообщение 13.6.2012, 17:36; Ответить: Arks
Сообщение #1


странное поведение, может кто сталкивался:

из БД выбираются 2 значения:
8372,660 и 4522,520 затем метод возвращает разность: 3850,14
в возврате var_dump выводит 3850,14, затем var_dump вызвавшего метода показывает 3850,13
0
Вернуться в начало страницы
 
Ответить с цитированием данного сообщения
Muxa_hb
Muxa_hb
сообщение 13.6.2012, 17:44; Ответить: Muxa_hb
Сообщение #2


(Arks @ 13.6.2012, 20:36) *
затем var_dump вызвавшего метода показывает 3850,13

че то я не могу сообразить как это :umnik:
Вернуться в начало страницы
 
Ответить с цитированием данного сообщения
alexdrob
alexdrob
сообщение 13.6.2012, 17:47; Ответить: alexdrob
Сообщение #3


[PHP]<?php

$a = floor((0.1+0.7)*10);
var_dump($a);[/PHP]
Результат 7.
Вернуться в начало страницы
 
Ответить с цитированием данного сообщения
alexdrob
alexdrob
сообщение 13.6.2012, 17:48; Ответить: alexdrob
Сообщение #4


http://php.net/manual/ru/language.types.float.php тут есть про это
Вернуться в начало страницы
 
Ответить с цитированием данного сообщения
Arks
Arks
Topic Starter сообщение 13.6.2012, 17:50; Ответить: Arks
Сообщение #5


Пардон, не 3850,13 а также 3850,14
Разница наступает если умножить значения на 100

Т.е. в приведенном ниже коде было
if ($cost > $cash)
if (3850,14 > 3850,14) //TRUE

[PHP]
$cash = $this->cash_model->getActiveCash($order['user_id'], $order['balance_type']);
//if ($cost > $cash) было - не работало
if (bccomp($cost, $cash, 2) === 1) { continue; }
[/PHP]

решилось с помощью BC но все равно странно
Вернуться в начало страницы
 
Ответить с цитированием данного сообщения
Arks
Arks
Topic Starter сообщение 13.6.2012, 20:47; Ответить: Arks
Сообщение #6


(alexdrob @ 13.6.2012, 20:47) *
$a = floor((0.1+0.7)*10);
var_dump($a);


это одно, про это в принципе я знал.. но во про тот бред что я увидел с возвращаемым значением это же вообще ни в какие рамки!
Т.е. было что-то типа

[PHP]function a() { //в примере выше это $cash = $this->cash_model->getActiveCash(...
$d = ......
var_dump($d); //3850,14 - правильно
return $d;
}

$r = a();
var_dump($r); //3850,13 - php сожрала копейку просто так при возврате значения[/PHP]
Вернуться в начало страницы
 
Ответить с цитированием данного сообщения
Arks
Arks
Topic Starter сообщение 28.6.2012, 22:44; Ответить: Arks
Сообщение #7


итак копейки продолжают атаковать мой мозг, т.к. я далек от математики в банковском деле...
пример:

есть поля - цена(DECIMAL 10,2), количество(int unsigned), коэфициент наценки(DECIMAL 3,2), процент уценки(DECIMAL 5,2)
например price = 526,08, quantity = 1, Kn = 1.17, Ku = 52.44
Сумма рассчитывается как CAST (price*quantity*Kn*Ku/100 AS DECIMAL(16,2))

Все бы было хорошо но при изменении этих четырех коэфициентов все начинает настолько сильно плавать что с каждой операцией накапливаются расхождения точности. Причина в ошибочных формулах/точности операций. Под операциями я имею в виду в данном случае различные проверки сохранения балансов, использующие ранее полученную по предыдущим коэфициентам сумму и пересчет на ее основе самих коэфициентов.

Может кто-то может предложить методику сохранения расхождения в формате 2 знаков после запятой, используемую в банковском деле?
Больше наверное интересует методика на php чем на SQL. BC я уже просто замучал, но идеальных моментов округления и формул пресчета так и не получил.
Вернуться в начало страницы
 
Ответить с цитированием данного сообщения
Arks
Arks
Topic Starter сообщение 21.7.2012, 9:52; Ответить: Arks
Сообщение #8


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

Пример методики:
56.97 = 56.97
56.971 = 56.98 (т.к. ближе к 56.98 чем к 56.96)
56.981 = 56.98 (т.к. ближе к 56.98 чем к 57.00)
56.969 = 56.96 (т.к. ближе к 56.96 чем к 56.98)
Вернуться в начало страницы
 
Ответить с цитированием данного сообщения
Muxa_hb
Muxa_hb
сообщение 21.7.2012, 11:32; Ответить: Muxa_hb
Сообщение #9


(Arks @ 21.7.2012, 12:52) *
56.971 = 56.98 (т.к. ближе к 56.98 чем к 56.96)
56.981 = 56.98 (т.к. ближе к 56.98 чем к 57.00)

имхо, первая строчка ближе к 56.97 чем к 56.98 или 56.96 - иначе следующее условие неправильно.
(Arks @ 21.7.2012, 12:52) *
56.969 = 56.96 (т.к. ближе к 56.96 чем к 56.98)

а это ближе к 56.97 чем к 56.96 ;)
Вернуться в начало страницы
 
Ответить с цитированием данного сообщения
Arks
Arks
Topic Starter сообщение 21.7.2012, 12:40; Ответить: Arks
Сообщение #10


да, я понимаю, но приводится именно к четным. Т.е. каждая пара нечетных(копеек) по статистике округлится к разным границам и округления в сумме поэтому дадут 0, если бы приводили к нечетным(из 56.969 к 56.97) то 0 бы не получался - одна тысячная бы пропадала в зависимости от типа при округлении точности из 0.001 к 0.01. А если число как раз нечетное но ровное (56.97), без тысячных ру***, то оно на статистике не сказывается(оно никак не округляется т.к. уже приведено к точности копейки 0.01) поэтому его к четным не приводят.
Короче говоря выбор ведется не на 0.005(больше-меньше) а до 0.01 статистически. Мы просто выкидываем тысячные, но мат.ожидание при большом количестве округлений всегда останется 0

Т.е. например есть число 56.971 - мы отбрасывает последнюю цифру - получили 56.97 - его последняя цифра нечетная. Определяем четные границы - 6 и 8, получаем пару 56.96 и 56.98 - смотрим какя разница по модулю меньше:
abs(56.971-56.96) = 0.011
abs(56.971-56.98) = 0.009
min(0.009, 0.011) = 0.009 => выбираем 56.98

При очень большом количестве разных чисел мы с одинаковой вероятностью будем получать как приведение к 56.96 так и к 56.98, их разница/2 = 0.01 что соответствует выбранной точности(1 копейка)

Согласитесь, изящное решение?

(Muxa_hb @ 21.7.2012, 14:32) *
иначе следующее условие неправильно.


(Muxa_hb @ 21.7.2012, 14:32) *
56.981 = 56.98 (т.к. ближе к 56.98 чем к 57.00)


Вы наверное не внимательно на цифру посмотрели - там 57.00, а не 56.97 - у меня все правильно написано
по методике:
56.981 - отбрасываем последнюю цифру, получаем 56.98 - последняя цифра четная, так что дальше уже не приводится, остается 56.98
Вернуться в начало страницы
 
Ответить с цитированием данного сообщения
2 страниц V   1 2 >
Открыть тему
Тема закрыта
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0


Свернуть

> Похожие темы

  Тема Ответов Автор Просмотров Последний ответ
Открытая тема (нет новых ответов) Хороший контент от нейросети за копейки
3 satherland 581 13.3.2024, 16:37
автор: malamut
Открытая тема (нет новых ответов) Продам сайт с флеш играми за копейки
0 alexey 822 2.2.2023, 12:16
автор: alexey
Открытая тема (нет новых ответов) Дешёвые сателлиты за копейки
1 MakDonald 1812 15.4.2020, 17:04
автор: MakDonald
Открытая тема (нет новых ответов) Тема имеет прикрепленные файлыМетод получения качественных ссылок за копейки (автоматизация 90%)
17 arthyrgrex 5429 28.2.2020, 21:13
автор: vladimir0vnk
Открытая тема (нет новых ответов) Качественное СЯ за копейки – работаю быстро, качественно, надёжно
Правильная семантика – стабильный рост трафика и профита!
3 LuckerMan 2947 5.9.2017, 11:30
автор: serg5777


 



RSS Текстовая версия Сейчас: 28.3.2024, 14:40
Дизайн