Форум: "Основная";
Текущий архив: 2004.07.04;
Скачать: [xml.tar.bz2];
Вниз
Правильное округление Найти похожие ветки
← →
Экспериментатор (2004-06-18 15:59) [0]Как правильно округлить некоторую величину? Round выполняет математическое округление, а мне нужно финансовое.
(интересует частный случай с четным числом и пятеркой насколько я помню - кто знает поймет)
← →
Тимохов © (2004-06-18 16:03) [1]
> (интересует частный случай с четным числом и пятеркой насколько
> я помню - кто знает поймет)
я много про это знаю, но не понимаю.
← →
Anatoly Podgoretsky © (2004-06-18 16:04) [2]У Round финансовое округление.
← →
Экспериментатор (2004-06-18 16:28) [3]Да уж. Ну и сформулировал я. К примеру
Round(48.3*095*100)/100 = 45.88
а должно быть 45,99
Почему так? И как исправить положение.
← →
Экспериментатор (2004-06-18 16:33) [4]Пардон - описка
должно быть 45,89
← →
Тимохов © (2004-06-18 16:34) [5]
> Пардон - описка
их там две.
гляньте setroundmode
← →
Экспериментатор (2004-06-18 16:41) [6]это есть в D6
TFPURoundingMode = (rmNearest, rmDown, rmUp, rmTruncate);
только в D5 Этого нет, а проект у меня на D5
Как же выйти из ситуации
← →
bSava © (2004-06-18 16:42) [7]
> Round(48.3*095*100)/100 = 45.88
> а должно быть 45,99
А вот я вам не верю!!!!!
Round работает немног подругому, (могу дать ссылку на хелп), ту же приведу следующий пример:
Если указанное значение аргумента находится ровно посредине между двумя целыми, например 1.5, то число округляется к четному целому,в данном случае к 2...
если не верите проверьте сам, я проверял, хелп не врет
← →
Anatoly Podgoretsky © (2004-06-18 16:44) [8]Потому что после (48.3*095*100)/100 у тебя число 45.88499999999999
← →
Экспериментатор (2004-06-18 16:52) [9]
> Потому что после (48.3*095*100)/100 у тебя число 45.88499999999999
Я в общем то понимаю что так,
но мне нужно как я написал,
не буду утверждать где правильно - тут или там
но даже Excel не показывает 45.88499999999999
хотя он его так хранит! он показывает 45,89 и калькулятор 45,89
в программе 45,88 - это не есть гуд
Что же мне предпринять чтобы было также
← →
Тимохов © (2004-06-18 16:55) [10]это зависит от режима округления процессора.
посмотрите это
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 17:03) [11]Попробовал на D6
Как ни странно результат тот же
// Round(48.3*0.95*100)/100 = 45,88
при любых значениях TFPURoundingMode
Чтобы это значило.
Может мне пора домой?
← →
ProgMan © (2004-06-18 17:08) [12]>Почему так? И как исправить положение.
Перед округлением прибавь 1e-6
← →
Anatoly Podgoretsky © (2004-06-18 17:11) [13]Да потому что 45,8849999999 никогда не преврятятся в 45,89 при любых масках, можно превранить 45,8850000000000 и то если с нестандартной маской
← →
Anatoly Podgoretsky © (2004-06-18 17:13) [14]ProgMan © (18.06.04 17:08) [12]
А что будешь делать с подлинной 45,8849999999, ведь тогда будет совсем неправильный результат. Он же не с константой работает, это число он привел для примера
← →
Экспериментатор (2004-06-18 17:14) [15]Действительно все работает. Надеюсь, больше ни на что это не повлияет
Попробовал - все ок!
ProgMan © - Thanks
Хотя интересно два момента:
- почему на D6 RoundMode не помог?
- какие еще варинты разрешения проблемы?
← →
Экспериментатор (2004-06-18 17:18) [16]Это не совсем пример
Это число - цена - скидка 5 процентов на нее,
вот и получается что не совсем как на калькуляторе,
потому и спрашиваю
а по поводу : почему на D6 RoundMode не помог?
наверно глупый вопрос задал
← →
Тимохов © (2004-06-18 17:23) [17]
> Экспериментатор (18.06.04 17:18) [16]
я в свое время с этим разбирался.
сам был в ужасе rounc(2.5) = 2!!!
при том, что и excel и sql sever дают 3.
как оказалось это зависит от режима округления процессора.
и такое округление нельзя называть неправильным - оно входит в некий стандарт - ieee 758 если не ошибаюсь (а скорее всего ошибаюсь - давно было). Там округлений описано - фигова туча: в спорных случаях от нуля, к нулю, всегда к нюлю, всегда от нуля, к четному и т.д.
Процессор не все режимы их этого стандарта поддерживает.
SETROUNDMODE по идее должен управлять режимами. почему у вас не получилось - не знаю. У меня работало в д6.
← →
ProgMan © (2004-06-18 17:28) [18]Anatoly Podgoretsky © (18.06.04 17:13) [14]
1. Что значит "С подлинной": при машинных операциях с плавающей запятой?
2. При таком количестве "девяток" вероятность, что это реальное число небольшая.
3. Для финансовых систем 2 знака после запятой достаточно.
А для особо привередливых можно повысить точность до 1e-8 ;-)
← →
Экспериментатор (2004-06-18 17:28) [19]да вот наверно из-за 45,8849999999 и не работает
Режимы RoundMode переключаются, проверил
← →
Экспериментатор (2004-06-18 17:29) [20]
> 3. Для финансовых систем 2 знака после запятой достаточно.
Наверное, да.
← →
Anatoly Podgoretsky © (2004-06-18 17:40) [21]ProgMan © (18.06.04 17:28) [18]
А ты что не можешь представить, что в результате вычислений будет такой результат и он будет именно истинный?
Твой алгоритм даст правильный результат для данного конкретного числа и очень много ошибок для других чисел.
Для особо привередливых есть функция FormatFloat а хранение в естественном, это уменьшает погрешность. Но нельзя превращать 45,8849999999 в 48,89
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2004.07.04;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.034 c