среда, 3 июня 2015 г.

Задачка 3

Что тут не так?

procedure TForm1.DoItClick(Sender: TObject);
var
 l_V : Double;
 l_I : Double;
begin
 l_V := StrToFloat(Edit1.Text);
 l_I := Int(l_V);
 lbInt.Caption := FloatToStr(l_I);
 lbFrac.Caption := FloatToStr(Frac(l_V));
end;

2 комментария:

  1. Для некоторых значений в дробной части может появиться погрешность. Frac() ожидает переменную типа Extended (10 байт, точность 19 знаков), а получает Double (8 байт, 15 знаков). Если я правильно понимаю, при этом происходит неявное приведение типов, «лишние» байты заполняются нулями, и может получиться немного другое значение (отличаться оно будет примерно в 16-м знаке от начала всего числа, не считая десятичную запятую, — то есть чем длиннее целая часть, тем раньше мы увидим ошибку в дробной).

    Убедиться в том, что виновата именно эта функция, легко: нужно вставить переменную X типа Extended:

    X := Frac(l_V); // после этой команды значение X уже будет с погрешностью
    lblFrac.Caption := FloatToStr(X);

    Кстати, на 64-битных системах этой ошибки, вроде, быть не должно, потому что там, согласно документации, Extended тоже 8 байт (проверить, увы, не могу): http://docwiki.embarcadero.com/RADStudio/XE8/en/Delphi_Data_Types

    ОтветитьУдалить