Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2004.09.19;
Скачать: [xml.tar.bz2];

Вниз

Проблема с 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;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.45 MB
Время: 0.033 c
11-1080734538
nester
2004-03-31 16:02
2004.09.19
Как в рантайм у формы поменять borderStyle?


1-1094027724
Соколов
2004-09-01 12:35
2004.09.19
Chart


3-1092706621
Вовчик
2004-08-17 05:37
2004.09.19
Не могу подключиться с серверу


10-1038816487
Calm
2002-12-02 11:08
2004.09.19
Материалы в помощь начинающим. Где их взять?


3-1092978298
sten
2004-08-20 09:04
2004.09.19
adoQuery





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский