0

I have a TDBEdit connected to a TFloatField which has DisplayFormat = '0.################'. I've set the field's value to 12.123456789 and I've noticed that my edit control displays it as '12,1234567890000005'.

enter image description here

I don't have a deep knowledge about floating point numbers but I know that this happens because floating point numbers are approximated.

Anyhow, I'm wondering how can I make sure that additional decimals will never "magically" appear after the user types a value?

I thought to shorten the DisplayFormat string by removing one '#' but I don't know if this would be sufficient to avoid the problem in any condition.

Example:

uses
  DBClient, DB, DBCtrls;

...

var
  Dst : TClientDataSet;
  Dsc : TDataSource;
  Fld : TFloatField;
  Edit : TDBEdit;
begin
  //components creation
  Dst := TClientDataSet.Create(Application);
  Dst.FieldDefs.Add('TEST', ftFloat, 0, False);
  Dst.CreateDataSet();

  Fld := Dst.Fields[0] as TFloatField;
  Fld.DisplayFormat := '0.################';

  Dsc := TDataSource.Create(Application);
  Dsc.DataSet := Dst;

  Edit := TDBEdit.Create(Application);
  Edit.DataSource := Dsc;
  Edit.DataField := Fld.FieldName;
  Edit.Align := alTop;
  Edit.Parent := Self;

  //test
  Dst.Open();
  Dst.Append();
  Fld.AsFloat := 12.123456789;
  Dst.Post();
Fabrizio
  • 7,603
  • 6
  • 44
  • 104
  • 2
    You can't avoid this, it's inherent with binary floating point. https://stackoverflow.com/questions/588004/is-floating-point-math-broken What you can do is use a decimal real data type instead of a binary real data type. In Delphi that would typically mean `Currency` although it's a bit limited. You might be better therefore with a third party decimal real data type. – David Heffernan May 15 '18 at 09:13
  • Well, strictly speaking, you can do better. Python 3.1 introduced a change in the way `repr` works for floating point values, so that it produces the shortest string which represents the actual value. Details here: https://bugs.python.org/issue1580 But there's nothing like that implemented in standard Delphi libraries. – David Heffernan May 15 '18 at 09:39
  • You can also use `ftFMTBCD` as field type. The corresponding field should be of type `TFMTBCDField` then. This field type has less restrictions than `ftBCD` - although also less performance.. – Uwe Raabe May 15 '18 at 10:26
  • "how can I make sure that additional decimals will never "magically" appear " --> As most FP use a binary base, insure the only decimal values used are also binary representable ones like 12.5, 12.0625, 12.0015411376953125, ... – chux - Reinstate Monica May 15 '18 at 13:28
  • @chux impractical – David Heffernan May 15 '18 at 15:36
  • @DavidHeffernan: Ok but isn't there a number of decimals which a [Double](http://docwiki.embarcadero.com/Libraries/Tokyo/en/System.Double) data type can represent without accuracy problems? – Fabrizio May 16 '18 at 07:28
  • @Fabrizio, I think you must accept the inaccuracies of binary floating point. To estimate the accuracy, see [How accurate is “double-precision floating-point format”?](https://stackoverflow.com/q/43836678/576719) – LU RD May 16 '18 at 07:47
  • @Fabrizio It's more complicated. You followed the link I gave you right? – David Heffernan May 16 '18 at 08:00
  • @DavidHeffernan I understand that accuracy problem is unavoidable but I just want to hide these problems to the user – Fabrizio May 16 '18 at 09:15
  • Never mind. I don't have a magic solution for you, and our communication doesn't seem to be working properly. – David Heffernan May 16 '18 at 09:31

0 Answers0