Главная страница
    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.46 MB
Время: 0.039 c
6-1089646712
Serg_lys
2004-07-12 19:38
2004.09.19
Работа с компонентом TNMSMTP применение кодировки


1-1094211874
BillyJeans
2004-09-03 15:44
2004.09.19
Показания датчика температуры CPU


3-1092977644
leonidus
2004-08-20 08:54
2004.09.19
Конвертация базы из dBase в Paradox


3-1092954088
Need Help
2004-08-20 02:21
2004.09.19
Использование запароленной базы данных Access через ADO


14-1093589496
saNat
2004-08-27 10:51
2004.09.19
Electronics Workbench





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