ven*_*eis 3 delphi precision tclientdataset bcd delphi-10-seattle
文档说:
TFMTBCDField 封装了二进制编码十进制 (BCD) 字段常见的基本行为。BCD 值比浮点数提供更高的精度和准确度。BCD 字段通常用于存储和操作货币值。
不幸的是,我发现将这样的字段与Extended值结合使用,我会失去精度(在本例中为两位数):如果我使用
BcdField.AsExtended := Value;
Run Code Online (Sandbox Code Playgroud)
该值实际上被截断为四位数字。对此我能做什么?
完整示例:
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;
Run Code Online (Sandbox Code Playgroud)
输出(在消息框中):
0,3333
0,333333333333333
Run Code Online (Sandbox Code Playgroud)
TField.AsBCD严格来说,使用返回记录会更准确TBcd。TFmtBcdField覆盖默认实现并返回准确的 TBcd记录。
TBcd是一种记录结构,支持简单的算术运算符以及从Integer和的隐式转换Double。所以它应该适合大多数用途。
缺点是:
Double或Integer参数的函数可能需要TBcd重载实现。一些相关注意事项:
Double如果由于浮点表示的本质而需要精确的精度,则使用是不合适的。请参阅浮点数学是否损坏?了解更多信息。Extended存在同样的问题-它仍然是浮点数据类型。此外,还有其自身的问题。请注意此处的警告。DoubleExtendedDouble使用BcdToDouble. 请参阅BCD 支持例程。Currency数据类型。它表示为 64 位整数,假定除以 10000,这就是它支持 4 位十进制数字的方式。