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
答案 0 :(得分:2)
严格来说,使用返回TField.AsBCD
记录的TBcd
会更准确。 TFmtBcdField
会覆盖默认实施并返回准确的 TBcd
记录。
TBcd
是一个记录结构,支持简单算术运算符和Integer
和Double
的隐式转换。所以它应该适合大多数用途。
缺点是:
Double
或Integer
参数的函数可能需要TBcd
重载实现。一些相关的考虑因素:
Double
的使用是不合适的。有关详细信息,请参阅Is floating point math broken?。Extended
与Double
具有相同的问题,即使额外的2个字节提供更大的范围和更高的精度 - 它仍然是浮点数据类型。此外,Extended
有其自身的问题。请注意警告here。Double
转换为BcdToDouble
。见BCD Support Routines。Currency
数据类型。它表示为64位整数,假设除以10000,它支持4位十进制数字。