TzMemTable - Float field

The offical for ZeosLib 7.3 Report problems, ask for help, post proposals for the new version of Zeoslib 7.3/v8
Quick Info:
-We made two new drivers: odbc(raw and unicode version) and oledb
-GUID domain/field-defined support for FB
-extended error infos of Firebird
-performance ups are still in queue
In future some more feature will arrive, so stay tuned and don't hassitate to help
Post Reply
kjteng
Senior Boarder
Senior Boarder
Posts: 54
Joined: 10.05.2015, 15:02

TzMemTable - Float field

Post by kjteng »

The following picuture shows a dbgrid which gets its data from a TZMemTable.
Some numbers are displayed as what I keyed in (eg. 1234.0, 1234.2, 1234.3) but some number are displayed with many decimals.
Something to do with the setting for the memtable, or the dbgrid ? Any help?
(Certainly I can set the display format to show all figures in two decimals, but it would be quite troublesome)
Screenshot (69).png
You do not have the required permissions to view the files attached to this post.
marsupilami
Platinum Boarder
Platinum Boarder
Posts: 1956
Joined: 17.01.2011, 14:17

Re: TzMemTable - Float field

Post by marsupilami »

Hello kjteng,

this has to do with the semantics of a Float. Not all decimal numbers can be encoded as a float without requiring small alterations. This leads to the problem you see. The very same should happen on regular data fields.
If you need to store decimal plaxes in exactly the same way as they are entered, please use TBCDField or TFMTBCDField.

Best regards,

Jan
miab3
Zeos Test Team
Zeos Test Team
Posts: 1310
Joined: 11.05.2012, 12:32
Location: Poland

Re: TzMemTable - Float field

Post by miab3 »

Hi kjteng,

This way you can force formatting:

Code: Select all

procedure TForm1.Button5Click(Sender: TObject);
var i:Integer;
begin
   with ZMemTable1 do
   for i := 0 to FieldCount-1 do
   begin
     case Fields[i].DataType of
      ftFloat, ftBCD:
        TNumericField(Fields[i]).DisplayFormat := '0.000';
      ftCurrency:
        TNumericField(Fields[i]).DisplayFormat := '0.00';
     end;
  end;
end; 
Michał
kjteng
Senior Boarder
Senior Boarder
Posts: 54
Joined: 10.05.2015, 15:02

Re: TzMemTable - Float field

Post by kjteng »

marsupilami wrote: 14.11.2021, 18:06 Hello kjteng,

this has to do with the semantics of a Float. Not all decimal numbers can be encoded as a float without requiring small alterations. This leads to the problem you see. The very same should happen on regular data fields.
If you need to store decimal plaxes in exactly the same way as they are entered, please use TBCDField or TFMTBCDField.

Best regards,

Jan
Yes I understand that this is the nature of float data.
However, I still think it would be better if we can display the number in a more 'pleasant' way. For example Tmemdataset actually display the number based on 8 significant digits by default (which can be change) so that the numbers displayed will be the same as what the user keyed in. RXMemorydata also display the float based on precision (default is 0). May be you can consider: (i) to set default precision and (ii) to save the precision in SaveToStream. I have just created a helper file for my version of savetostream/loadfromstram (with the precision info). It seems to work.
I will post it for sharing/discussion later after more testing is done.
kjteng
Senior Boarder
Senior Boarder
Posts: 54
Joined: 10.05.2015, 15:02

Re: TzMemTable - Float field

Post by kjteng »

miab3 wrote: 14.11.2021, 20:02 Hi kjteng,

This way you can force formatting:

Code: Select all

procedure TForm1.Button5Click(Sender: TObject);
var i:Integer;
begin
   with ZMemTable1 do
   for i := 0 to FieldCount-1 do
   begin
     case Fields[i].DataType of
      ftFloat, ftBCD:
        TNumericField(Fields[i]).DisplayFormat := '0.000';
      ftCurrency:
        TNumericField(Fields[i]).DisplayFormat := '0.00';
     end;
  end;
end; 
Michał
Yeah. As mentioned in my post earlier, I was doing it this way. However, I later I discovered that in some cases setting the precision property may be more appropriate (because the users want to see what exactly they have keyed in, i.e. 1.23 and 1.2300 has different meaning to them)
marsupilami
Platinum Boarder
Platinum Boarder
Posts: 1956
Joined: 17.01.2011, 14:17

Re: TzMemTable - Float field

Post by marsupilami »

Hello kjteng,
kjteng wrote: 15.11.2021, 06:32 Yes I understand that this is the nature of float data.
However, I still think it would be better if we can display the number in a more 'pleasant' way. For example Tmemdataset actually display the number based on 8 significant digits by default (which can be change) so that the numbers displayed will be the same as what the user keyed in. RXMemorydata also display the float based on precision (default is 0). May be you can consider: (i) to set default precision and (ii) to save the precision in SaveToStream. I have just created a helper file for my version of savetostream/loadfromstram (with the precision info). It seems to work.
I will post it for sharing/discussion later after more testing is done.
I have to disagree about setting the default value of T(Z)FloatField.Precision. This is what I found on Embarcaderos Help on TFloatField.Precision:
Embarcadero online help on Data.DB.TFloatField.Precision wrote:The default value of Precision is 15 decimal places.
I see no reason to do it different because this way the user gets to see the full numer that is stored. If a user needs less significant places, it is the users responsibility to change this value.

But I agree that LoadFromStream and SaveToStream should save the properties of the fields, if possible.

Best regards,

Jan
kjteng
Senior Boarder
Senior Boarder
Posts: 54
Joined: 10.05.2015, 15:02

Re: TzMemTable - Float field

Post by kjteng »

Hi Marsupilami,

I tried the following code (to set precision when I create a table) but failed (it always return -1, same code works for TMemDataSet).
with zmemtable1 do
begin
Close;
FieldDefs.Clear;
FieldDefs.Add('aa', ftFloat, 0, True);
FieldDefs.Items[0].Precision:= 12;
Open;
showmessage(IntToStr(TFloatField(Fieldbyname('aa')).Precision))
end;

Do I missed out anything? (BTW setting TFloatField(Fieldbyname('AAA')).precision := 12 after opening the zmemtable seems to work)
Post Reply