【发布时间】:2017-12-12 20:46:09
【问题描述】:
TFMTBCDField 封装了二进制编码十进制 (BCD) 字段常见的基本行为。 BCD 值比浮点数提供更高的精度和准确度。 BCD 字段通常用于存储和操作货币值。
不幸的是,我发现将这样一个字段与 Extended 值结合使用,我会失去精度(在本例中为两位数):如果我使用
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
【问题讨论】:
-
嗯,定义为
ftExtended? -
好的,但大多数时候我们使用
MSSQL和NUMERIC(..)字段,这导致delphi 端有ftFmtBcd字段。我不想更改数据库中的字段... -
这似乎是西雅图的问题。刚在东京试过,很惊讶它的工作原理。可能与quality.embarcadero.com/browse/RSP-16200有关?
-
试试
LFieldDef.Size := 15; LFieldDef.Precision := 15;。 -
严格来说,使用返回TBcd 记录的
TField.AsBCD会更准确。但是可能有问题...我没有最新版本来检查源代码,但是当前文档指出:TFMTBCDField.Value与AsBCD相同,后者又“返回转换后的 AsCurrency 的值到一个 TBcd 值”。这意味着一个错误,即通过Currency,一个专门用于支持比TBCD更高精度的字段在任何情况下都被限制为Currency精度。
标签: delphi precision delphi-10-seattle tclientdataset bcd