Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Правильное округление


Страницы:   1 2

Экспериментатор ©   (2004-06-18 15:59:00) 

Как правильно округлить некоторую величину? Round выполняет математическое округление, а мне нужно финансовое.
(интересует частный случай с четным числом и пятеркой насколько я помню - кто знает поймет)


Anatoly Podgoretsky   (2004-06-18 17:40:00) [1]

ProgMan ©   (18.06.04 17:28) [18]
А ты что не можешь представить, что в результате вычислений будет такой результат и он будет именно истинный?
Твой алгоритм даст правильный результат для данного конкретного числа и очень много ошибок для других чисел.
Для особо привередливых есть функция FormatFloat а хранение в естественном, это уменьшает погрешность. Но нельзя превращать 45,8849999999 в 48,89


Экспериментатор   (2004-06-18 17:29:00) [2]


> 3. Для финансовых систем 2 знака после запятой достаточно.

Наверное, да.


Экспериментатор   (2004-06-18 17:28:00) [3]

да вот наверно из-за 45,8849999999 и не работает
Режимы RoundMode переключаются, проверил


ProgMan   (2004-06-18 17:28:00) [4]

Anatoly Podgoretsky ©   (18.06.04 17:13) [14]

1. Что значит "С подлинной": при машинных операциях с плавающей запятой?
2. При таком количестве "девяток" вероятность, что это реальное число небольшая.
3. Для финансовых систем 2 знака после запятой достаточно.

А для особо привередливых можно повысить точность до 1e-8 ;-)


Тимохов   (2004-06-18 17:23:00) [5]


> Экспериментатор   (18.06.04 17:18) [16]

я в свое время с этим разбирался.
сам был в ужасе rounc(2.5) = 2!!!
при том, что и excel и sql sever дают 3.

как оказалось это зависит от режима округления процессора.

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

Процессор не все режимы их этого стандарта поддерживает.

SETROUNDMODE по идее должен управлять режимами. почему у вас не получилось - не знаю. У меня работало в д6.


Экспериментатор   (2004-06-18 17:18:00) [6]

Это не совсем пример
Это число - цена - скидка 5 процентов на нее,
вот и получается что не совсем как на калькуляторе,
потому и спрашиваю
а по поводу : почему на D6 RoundMode не помог?
наверно глупый вопрос задал


Экспериментатор   (2004-06-18 17:14:00) [7]

Действительно все работает. Надеюсь, больше ни на что это не повлияет
Попробовал - все ок!

ProgMan © - Thanks

Хотя интересно два момента:
- почему на D6 RoundMode не помог?
- какие еще варинты разрешения проблемы?


Anatoly Podgoretsky   (2004-06-18 17:13:00) [8]

ProgMan ©   (18.06.04 17:08) [12]
А что будешь делать с подлинной 45,8849999999, ведь тогда будет совсем неправильный результат. Он же не с константой работает, это число он привел для примера


Anatoly Podgoretsky   (2004-06-18 17:11:00) [9]

Да потому что 45,8849999999 никогда не преврятятся в 45,89 при любых масках, можно превранить 45,8850000000000 и то если с нестандартной маской


ProgMan   (2004-06-18 17:08:00) [10]

>Почему так? И как исправить положение.
Перед округлением прибавь 1e-6


Экспериментатор   (2004-06-18 17:03:00) [11]

Попробовал на D6
Как ни странно результат тот же
//  Round(48.3*0.95*100)/100  = 45,88
при любых значениях TFPURoundingMode
Чтобы это значило.
Может мне пора домой?


Тимохов   (2004-06-18 16:55:00) [12]

это зависит от режима округления процессора.
посмотрите это

function SetRoundMode(const RoundMode: TFPURoundingMode): TFPURoundingMode;
var
 CtlWord: Word;
begin
 CtlWord := Get8087CW;
 Set8087CW((CtlWord and $F3FF) or (Ord(RoundMode) shl 10));
 Result := TFPURoundingMode((CtlWord shr 10) and 3);
end;


Экспериментатор   (2004-06-18 16:52:00) [13]


> Потому что после (48.3*095*100)/100  у тебя число 45.88499999999999

Я в общем то понимаю что так,
но мне нужно как я написал,
не буду утверждать где правильно -  тут или там
но даже Excel не показывает 45.88499999999999
хотя он его так хранит! он показывает 45,89 и калькулятор 45,89
в программе 45,88 - это не есть гуд
Что же мне предпринять чтобы было также


Anatoly Podgoretsky   (2004-06-18 16:44:00) [14]

Потому что после (48.3*095*100)/100  у тебя число 45.88499999999999


bSava   (2004-06-18 16:42:00) [15]


> Round(48.3*095*100)/100 = 45.88
> а должно быть 45,99

А вот я вам не верю!!!!!
Round работает немног подругому, (могу дать ссылку на хелп), ту же приведу следующий пример:

Если указанное значение аргумента находится ровно посредине между двумя целыми, например 1.5, то число округляется к четному целому,в данном случае к 2...

если не верите проверьте сам, я проверял, хелп не врет


Экспериментатор   (2004-06-18 16:41:00) [16]

это есть в D6
TFPURoundingMode = (rmNearest, rmDown, rmUp, rmTruncate);
только в D5 Этого нет, а проект у меня на D5

Как же выйти из ситуации


Тимохов   (2004-06-18 16:34:00) [17]


> Пардон - описка

их там две.

гляньте setroundmode


Экспериментатор   (2004-06-18 16:33:00) [18]

Пардон - описка
должно быть 45,89


Экспериментатор   (2004-06-18 16:28:00) [19]

Да уж. Ну и сформулировал я. К примеру
Round(48.3*095*100)/100 = 45.88
а должно быть 45,99
Почему так? И как исправить положение.


Anatoly Podgoretsky   (2004-06-18 16:04:00) [20]

У Round финансовое округление.


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо