Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Для новичков > Проблемы с Trunc


Автор: BaD_SeCt0R 30.9.2007, 20:57
ВОПРОС:

Код

procedure TForm1.Button1Click(Sender: TObject);
var       MX, MX0, LS, ML, d: Double;
begin
          LS := 1;
          ML := 0.1;

          d := LS/ML;
          MX := Trunc(LS/ML);
          MX0 := Trunc(d);    // по идее MX0 должен быть равен MX
          Label1.Caption := FloatToStr(MX);
          Label2.Caption := FloatToStr(MX0);
end;


На выходе у меня получается, что:
MX = 9
MX0 = 10

Как это объяснить? И что делать? Хотелось бы отправлять в Trunc (или другую подобную функцию) любые формулы, и чтобы таких багов не было.

ОТВЕТ:

 Ну скажем число 2.34367 - без периода, а скажем число 2 / 3 = 0,66666(6) число с периодом, т.е. сколько десятичных чисел не добавляй, все равно будет погрешность. Но это десятичные числа, двоичные числа тоже бывают дробные, например 110,10001110. Так вот дробные числа в компутере принято представлять именно двоичной форме (как в последнем примере). Но вот есть незадача, не все числа без периода, такие как "2.34367" (т.е. точное число) можно представить в виде точной последовательности нулей и единиц как 110,10001110, часто получаются последовательности типа 110,10001110(101), т.е. что было точным стало неточным. Т.е. точность результата зависит от метода вычисления того или иного выражения. Вот и получилось, что результат в одном случае получился точнее чем в другом из-за того что при компиляции получился разный код.

Для положительных чисел можно исправить так.

Код

procedure TForm1.Button1Click(Sender: TObject);
var       MX, MX0, LS, ML, d: Double;
begin
          LS := 1;
          ML := 0.1;
          d := LS/ML;
          MX := Trunc(LS/ML + 0,000001);
          MX0 := Trunc(d  + 0,000001);    // по идее MX0 должен быть равен MX
          Label1.Caption := FloatToStr(MX);
          Label2.Caption := FloatToStr(MX0);


Для отрицательных

Код

procedure TForm1.Button1Click(Sender: TObject);
var       MX, MX0, LS, ML, d: Double;
begin
          LS := 1;
          ML := 0.1;
          d := LS/ML;
          MX := Trunc(LS/ML - 0,000001);
          MX0 := Trunc(d  - 0,000001);    // по идее MX0 должен быть равен MX
          Label1.Caption := FloatToStr(MX);
          Label2.Caption := FloatToStr(MX0);


Автор ответа: http://forum.vingrad.ru/index.php?showuser=777&nickname=Alexeis

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)