Главная страница
    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.034 c
1-1094392347
ZLG
2004-09-05 17:52
2004.09.19
Как сохранить состояние CheckBox, radiobutton, edit


10-1034651971
Comwad
2002-10-15 07:19
2004.09.19
Глюк в Delphi 7 или VB4.5 (Пример Midas XML)


3-1092904093
Dionnis
2004-08-19 12:28
2004.09.19
Запрос на SQL с группировкой данных


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


1-1094188938
Death
2004-09-03 09:22
2004.09.19
Настройка внутренней сети





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский