Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.09.19;
Скачать: CL | DM;

Вниз

Проблема с trunc   Найти похожие ветки 

 
KA_ ©   (2004-09-04 16:42) [0]

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 !

Спасибо.


 
Defunct ©   (2004-09-04 16:50) [1]

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

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

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

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

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

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

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

I := Round(D1);


 
Pat ©   (2004-09-04 16:54) [2]

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

var
D: Extended;


 
KA_ ©   (2004-09-04 17:17) [3]

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

Вот функция округления вещественного числа до 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 :(((


 
Defunct ©   (2004-09-04 17:38) [4]

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


 
Defunct ©   (2004-09-04 17:45) [5]

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

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.


 
KA_ ©   (2004-09-04 17:52) [6]

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



Страницы: 1 вся ветка

Текущий архив: 2004.09.19;
Скачать: CL | DM;

Наверх




Память: 0.48 MB
Время: 0.05 c
6-1089395762
rOOse
2004-07-09 21:56
2004.09.19
HTML формы


1-1093938194
Cosinus
2004-08-31 11:43
2004.09.19
Несколько вложенных try. Корректность использования.


14-1093324128
Stany
2004-08-24 09:08
2004.09.19
поднятие IRC сервера под винду


14-1093472027
Гарри Поттер
2004-08-26 02:13
2004.09.19
Outpost vs DMClient


4-1091963401
Sadist BOB
2004-08-08 15:10
2004.09.19
панель задач