Форум: "Основная";
Текущий архив: 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