Главная страница
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.061 c
14-1093770941
able
2004-08-29 13:15
2004.09.19
Вопрос по ноутбукам.


14-1093580852
тихий вовочка
2004-08-27 08:27
2004.09.19
Как заработать


14-1094114473
maksim
2004-09-02 12:41
2004.09.19
удаление символов строки при нажатии кнопки


6-1089646712
Serg_lys
2004-07-12 19:38
2004.09.19
Работа с компонентом TNMSMTP применение кодировки


14-1094036140
Real
2004-09-01 14:55
2004.09.19
Восстановление нормальной загрузки Win9x - Win2000 - Linux