Округление чисел в "Финансах без проблем"



Posted by Анатолий Анимица on June 29, 1999 at 10:22:42:

In Reply to: Неужели я нашел ошибку? posted by Олег, Тула on June 27, 1999 at 13:49:53:

Округление чисел в программах на языке "Финансы без проблем" (ФБП) - не совсем тривиальная задача, связанная с наличием различных обработчиков (16-разрядные UltraH и Ultra Windows и 32-разрядные серверы различных модификаций), в результате чего получаются разные результаты округления.
Как правильно заметил Олег из Тулы, [ro 0.5]=0 в Ultra и 1 в сервере. Такое различие получается на четных целых частях числа, а на нечетных - результаты совпадают. Поскольку числа бывают еще и отрицательными (про мнимые и прочие квартероны здесь умолчим), разумно оформить округление как процедуру, точнее, процедуру-функцию, в том смысле, что на вход процедуры подается некоторое число, и оно же образует ее выход. Конечно, в языке ФБП не определено понятие процедуры, но уже привычная всем подпрограмма при определенном оформлении вполне ее заменит.
Итак, процедуры округления: разумно написать две "быстрых" - одну для округления числа до целого и одну до одной сотой (допустим, копейки), и одну "более медленную" - для округления числа с заданным количеством знаков после десятичной точки. Не забываем, что это - просто подпрограммы с явной передачей данных по значению.


*
:ro подпрограмма округления числа до целого вход и выход ro
if ro>0 ro=[tr ro+0.5]
elseif ro<0 ro=[tr ro-0.5]
endif
return ro
* обращение к подпрограмме: ro=x;call ro;x=ro \ здесь x - число, которое мы округляем до 1.
*
:ro2 подпрограмма округления числа до 0.01 вход и выход ro
if ro>0 ro=[tr ro*100+0.5]/100
elseif ro<0 ro=[tr ro*100-0.5]/100
endif
return ro2
* обращение к подпрограмме: ro=x;call ro2;x=ro \ здесь x - число, которое мы округляем до 0.01
*
:ron подпрограмма округления числа до n знаков после(n>=0) и перед(n<0) точкой вход n,ro выход ro
if n=0 or=1
elseif n in 1..6 or=1;for i=1 to n or=or*10;endfor
elseif n in -6..-1 or=1;for i=1 to -n or=or/10;endfor
else error конечно, можно и округлить, но стоит ли?
endif
if ro>0 ro=[tr ro*or+0.5]/or
elseif ro<0 ro=[tr ro*or-0.5]/or
endif
return ron
* обращение к подпрограмме: ro=x;n=-6..6;call ron;x=ro \ здесь x - число, которое мы округляем
до 0.01


Ни одна живая душа это не тестировала. Никакая Ultra или сервер этих текстов не видели. По-хорошему надо бы на них тестик написать, примерно по 10 вхождений в каждый ранг округления, и еще бы протокол с автоконтролем ошибки сделать, каковую задачу я и предлагаю читателям этого текста. Если нам удастся наладить публикацию "свидетельств" - по образцу старого доброго CACM (был такой журнал, в ФБПАМИНИ есть на него одна ссылка) - это и будет "народная сертификация" ФБП. Библиотека свидетельств в CACM превысила размер самих текстов алгоритмов в несколько раз. Как оно и должно быть.

Заявление. Несмотря на свою нынешнюю должность в "Хакерс Дизайн", здесь на wwwboard я простой советский программист и не более того. Попрошу уважаемых коллег именно так и расценивать мои собщения, реплики, анекдоты и так далее. Благодарю за внимание

AAA




Пpишедшие ответы: