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

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

Округление чисел в Delphi [D7, Win2k]


АМБ ©   (2005-03-01 13:40:00) 

Подскажите как организовать округление чисел с заданой точностью в Delphi. Я сделал свою функцию основанную на round. Но у нее обнаружилась странная особенность.
Round(1.5) = 2, а Round(2.5)=2, тоже. Т.е. только 1.5 округляет до 2, а что больше (2.5, 3.5, и т.д.) округляет в меньшую сторону. Как сделать, чтобы округление 0.5 всегда шло в большую сторону.


mike-d   (2005-03-01 17:43:00) [1]

Since Delphi's Round() function uses "bankers rounding" where the value is rounded to the nearest even number, how can I round a floating point number using the more  traditional means, where fractional values less than .5 round down, and fractional values of .5 and greater round up?

Answer:

The following function demonstrates rounding down numbers with  fractional values of less than .5, and rounding up numbers with  fractional values of .5 and greater.

Example:

function RoundUp(X: Extended): Extended;
begin
  Result := Trunc(X) + Trunc (Frac(X) * 2);
end;


http://www.ibase.ru/devinfo/round.htm- полное обсуждение...


Antonn   (2005-03-01 17:06:00) [2]

Sancho ©   (01.03.05 16:35) [15]
как вариант: умножать на 100, округлять, делить на 100, удалять знаки в дробной части(если больше 2х)


Sancho   (2005-03-01 16:35:00) [3]

Я прочитал эту ветку попробовал RoundTo(1734.5, 0) = 1735, а вот RoundTo(123.125, -2) = 123.12. Так как в Delphi правильно округлить до, к примеру, 2-х знаков после запятой ? Кстати вот так работает правильно FormatFloat('0.00', 123.125), но это же строки.


АМБ   (2005-03-01 16:29:00) [4]

Всем спасибо.
В результате получилось
MyFankRound := (SimpleRoundTo(N*R, 0))/R;
где N - округляемое число;
   R - указатель точности округления. Правда не много не удобное. Если указываешь точность после запятой, то указываешь в целых величинах. Например, для точности до десятых, указываешь 10, до сотых - 100. А если надо округлять до целых десятков, то указываешь 0.1, до сотых - 0.01
Еще раз всем спасибо.


begin...end   (2005-03-01 15:28:00) [5]

> АМБ   (01.03.05 15:17) [12]

А надо 1735? Используйте RoundTo(1734.5, 0).


АМБ   (2005-03-01 15:17:00) [6]


> begin...end ©   (01.03.05 15:15) [10]

Прошу прощения. Не правильно записал. Надо
round(1734.5) = 1736
а потом я еще и делю на коэфициент.


MU   (2005-03-01 15:15:00) [7]

попробуй [7]  :)


begin...end   (2005-03-01 15:15:00) [8]

> АМБ   (01.03.05 15:11) [9]

Round возвращает целое число.


АМБ   (2005-03-01 15:11:00) [9]


> begin...end ©   (01.03.05 14:52) [8]


Устанавливаю:  SetRoundMode(rmUp);
После этого программа выдает:
Round(17.345) = 17.36
???


begin...end   (2005-03-01 14:52:00) [10]

> АМБ   (01.03.05 13:57) [5]
> а как сделать, чтобы 5 округлялась в большую сторону?

См. в справке описание функции SetRoundMode.


MU   (2005-03-01 14:32:00) [11]

есть у меня такая ТУПАЯ и НЕКРАСИВАЯ функция, но она удовлетворила всем нашим требованиям.

function SRoundTo(const AValue: Extended; const ADigit: TRoundToRange = -2): Extended;
var wS : String;
   V : Extended;
   i, P, PGreat, S : Integer;
begin
 S := Sign(AValue);
 V := Abs(AValue);
 wS := FormatFloat('0.0000#', V);
 P := Pos('.', wS) - ADigit;
 PGreat := P;
 if (P + 1 <= Length(wS)) and (P > 1) then
   if ws[P+1] > '4' then
     repeat
       if ws[P] = '.' then
         Dec(P);
       while ws[P] = '9' do
       begin
         wS[P] := '0';
         if P = 1 then
           wS := '0' + wS
         else
           Dec(P);
         if ws[P] = '.' then
           Dec(P);
       end;
       if ws[P] <> '.' then
       begin
         wS[P] := Succ(wS[P]);
         Break;
       end;
     until true;
 for i := PGreat + 1 to Length(wS) do
   if wS[i] <> '.' then ws[i] := '0';
 Result := S * StrToFloat(wS);
end;


Думкин   (2005-03-01 14:20:00) [12]

> [4] АМБ   (01.03.05 13:47)
> Что не верно? Поясните.


а что больше (2.5, 3.5, и т.д.) округляет в меньшуюсторону.

If X is exactly halfway between two whole numbers, the result is always the even number. This method of rounding is often called "Banker’s Rounding".

Доступно?


АМБ   (2005-03-01 13:57:00) [13]

SimpleRoundTo(4.145, -2) = 4.14
и
RoundTo(4.145, -2) = 4.14
т.е. 5 округляется в меньшую сторону, а как сделать, чтобы 5 округлялась в большую сторону?


АМБ   (2005-03-01 13:47:00) [14]


> Думкин ©   (01.03.05 13:44) [1]


> Не верно.


Что не верно? Поясните.


Думкин   (2005-03-01 13:45:00) [15]

> Подскажите как организовать округление чисел с заданой точностью в Delphi.

А это RoundTo + F1


MU   (2005-03-01 13:45:00) [16]

SimpleRoundTo


Думкин   (2005-03-01 13:44:00) [17]

> Round(1.5) = 2, а Round(2.5)=2, тоже. Т.е. только 1.5 округляет
> до 2, а что больше (2.5, 3.5, и т.д.) округляет в меньшую
> сторону.

Не верно.

If X is exactly halfway between two whole numbers, the result is always the even number. This method of rounding is often called "Banker’s Rounding".


Наверх

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