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

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

Проблема с trunc [D7, Win2k]


KA_ ©   (2004-09-04 16:42:00) 

Delphi 7.

program trunctest;

{$APPTYPE CONSOLE}

uses
 SysUtils;

var
 D: Double;
   I: Integer;
begin
 D := 1297.85;        
   D := D * 100;    // D = 129785.0
   I := Trunc(D1);  // I = 129784 !!!!!!!
   if I <> 129785 then
     WriteLn(Format('Trunc Error! I=%d, D=%f', [I, D]))
 else
   WriteLn('Oll Korrect!');
 ReadLn;
end.


Всегда происходит ошибка, хотя ее не должно быть
Подскажите, как избежать такой ошибки, и откуда ростут ноги такого поведения Delphi !

Спасибо.


KA_   (2004-09-04 17:52:00) [1]

>Defunct ©   (04.09.04 17:45) [5]
Спасибо.


Defunct   (2004-09-04 17:45:00) [2]

подумал может это из-за того, что приложение консольное,
однако взгляните на это:

program Project2;

{$APPTYPE CONSOLE}

uses
 SysUtils;

Var D:Double;
begin
 { TODO -oUser -cConsole Main : Insert code here }
 D := 1297.85;
 D := D*100;

 WriteLn('Round(D) = ', Round(D));
 WriteLn('Trunc(D) = ', Trunc(D+0.0000001));
 ReadLn;
end.


Результат в обоих случаях 129785.


Defunct   (2004-09-04 17:38:00) [3]

procedure TForm1.Button2Click(Sender: TObject);
Var D:Double;
   I:Integer;
begin
 D := 1297.85;
 D := D*100;
 I := Round(D);
 ShowMessage( Format('%D',[i]));
 I := Trunc(D+0.0000001);
 ShowMessage( Format('%D',[i]));
end;


В обоих случаях I = 129785


KA_   (2004-09-04 17:17:00) [4]

Спасибо, но к сожалению ни один совет не помог :(

Вот функция округления вещественного числа до N-ого знака после запятой:

function RoundX(const X: Double; DigitsAfterDot: Integer): Double;
var
 LFactor, D1, D2: Extended;
 X1, X2, I: Integer;
begin
 LFactor := IntPower(10, DigitsAfterDot);
 D1 := X * LFactor;
 I := Trunc(D1 + 0.000000000001);
 X1 := I * 10;
 D2 := X * LFactor * 10;
 X2 := Trunc(D2 + 0.000000000001);
 if (X2 - X1) > 4 then
   Inc(I);
 Result := I / LFactor;
end;

При округлении 1297.85 до двух щнаков после запятой (хотя оно и не требуется) получим 1297.84 :(((


Pat   (2004-09-04 16:54:00) [5]

http://www.delphikingdom.com/asp/viewitem.asp?UrlItem=/helloworld/reals.htm

var
D: Extended;


Defunct   (2004-09-04 16:50:00) [6]

не все числа можно однозначно записать в форме с плавающей запятой.

в приведенном примере число 1297.85 записывается как 1297.84[9]

домнажая на 100 получается 129784.[9]

Truncотсекает [9], отсюда и результат.

Избежать можно добавлением E=0.[0]1 (коррекция для Trunc)

например:
I:=Trunc(D1+0.000000000001);

либо используя Round.

I := Round(D1);


Наверх

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