Question

While maintaining some code, I came across this statement:

 sActDiln := Format('%.*f',[tdDigits.ndd, Fields[itd].AsFloat * rfc / 100]);

In order to see what was going on, I added a temporary variable (actDiln) of type DOUBLE and altered the code as follows:

 actDiln := Fields[itd].AsFloat * rfc / 100;
 sActDiln := Format('%.*f',[tdDigits.ndd, actDiln]);

When "Fields[itd].AsString" is 35 and "rfc" is 109, the computed value changed from 38.15 to 38.14999999. When the number of decimal digits was 1, this then changed the computed value from 38.2 to 38.1. And this caused other problems.

I did not anticipate that using this temporary variable would cause such problems. Can anyone explain what is going on here? And what is best practice in the future to avoid this?

This demonstrates the problem:

Uses DB, DBISAMTb;

procedure TForm1.FormShow(Sender: TObject);
   var
      t : TDBISAMTable;
      actDiln, rfc : double;
      actDilnE : extended;
      sActDiln1, sActDiln2, sActDiln3 : string;
   begin
   t := TDBISAMTable.Create(Application);

   WITH t DO BEGIN
      TableName := 'xxx';
      DataBaseName := 'Study';

      Active := False;
      Exclusive := False;
      IF Exists THEN DeleteTable;

      WITH FieldDefs DO BEGIN
         Clear;
         Add('fld', ftString, 10, False);
         END;
      WITH IndexDefs DO BEGIN
         Clear;
         END;
      CreateTable;
      Exclusive := True; //<<<<<<<<<<<<<
      IndexName := '';
      Open;
      Append;
      FieldByName('fld').AsString := '35';
      Post;

      rfc := 109;

      actDiln := Fields[0].AsFloat * rfc / 100;
      sActDiln1 := Format('%.*f',[1, Fields[0].AsFloat * rfc / 100]);
      sActDiln2 := Format('%.*f',[1, actDiln]);
      actDilnE := Fields[0].AsFloat * rfc / 100;
      sActDiln3 := Format('%.*f',[1, actDilnE]);
      ShowMessage(sActDiln1 + ' vs ' + sActDiln2 + ' vs ' + sActDiln3);
      end;
   end;
Était-ce utile?

La solution

Inline floating-point calculations are usually of Extended type. Check the behavior when your intermediate variable is Extended too.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top