gpt4 book ai didi

delphi - 如何避免 ftFmtBcd 失去精度?

转载 作者:行者123 更新时间:2023-12-03 15:51:29 30 4
gpt4 key购买 nike

documentation说:

TFMTBCDField encapsulates the fundamental behavior common to binary-coded decimal (BCD) fields. BCD values provide greater precision and accuracy than floating-point numbers. BCD fields are often used for storing and manipulating monetary values.

不幸的是,我发现将这样的字段与扩展值结合使用,我会失去精度(在本例中为两位数):如果我使用

BcdField.AsExtended := Value;

该值实际上被截断为四位数字。对此我能做什么?

完整示例:

procedure TForm1.Button1Click(Sender: TObject);
var
LValue: Double;
LDataset: TClientDataSet;
LFieldDef: TFieldDef;
begin
LValue := 1 / 3;
LDataset := TClientDataSet.Create(self);
try
LFieldDef := LDataset.FieldDefs.AddFieldDef;
LFieldDef.DataType := ftFMTBcd;
LFieldDef.Size := 6;
LFieldDef.Precision := 10;
LFieldDef.Name := 'A';
LDataset.CreateDataset;
LDataset.Append;
LDataset.FieldByName('A').AsExtended := LValue;
LDataset.Post;
ShowMessage(FloatToStr(LDataset.FieldByName('A').AsExtended));
ShowMessage(FloatToStr(LValue));
finally
FreeAndNil(LDataset);
end;
end;

输出(在消息框中):

0,3333
0,333333333333333

最佳答案

严格来说,使用 TField.AsBCD 会更准确。它返回 TBcd记录。 TFmtBcdField 覆盖默认实现并返回准确 TBcd 记录。

TBcd 是一种记录结构,支持简单算术运算符以及从 IntegerDouble 进行隐式转换。因此它应该适合大多数用途。

缺点是:

  • 由于缺乏内置机器指令,数学运算可能会稍微慢一些。但对于需要精确表示的情况来说,这可能是一个合理的权衡。 根据需要进行基准测试和评估。
  • 某些采用 DoubleInteger 参数的函数可能需要 TBcd 重载实现。
<小时/>

一些相关注意事项:

  • 如果由于浮点表示的本质而需要精确的精度,则使用 Double 是不合适的。请参阅Is floating point math broken?了解更多信息。
  • 使用 ExtendedDouble 存在相同的问题,尽管额外的 2 个字节提供了更大的范围和更高的精度 - 它仍然是 float 据类型。此外,Extended 有其自身的问题。请注意警告 here .
  • 如果您不需要精确的表示形式,则可以使用 BcdToDouble 转换为 Double。请参阅BCD Support Routines .
  • 如果您不需要超过 4 位小数,但确实需要精确表示,则可以考虑另一个选项:使用 Currency数据类型。它表示为 64 位整数,假定除以 10000,这就是它支持 4 位十进制数字的方式。

关于delphi - 如何避免 ftFmtBcd 失去精度?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47781249/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com