Delphi中BCD和Currency类型
Delphi中BCD和Currency类型
一. BCD类型
BCD即Binary-Coded Decimal,在Delphi中,BCD字段类型可以精确保存浮点数据类型。
Delphi支持的BCD码的数据类型名为TBCD,它的定义如下:
TBcd = packed record Precision: Byte; { 1..64 } SignSpecialPlaces: Byte; { Sign:1, Special:1, Places:6 } Fraction: packed array [0..31] of Byte; { BCD Nibbles, 00..99 per Byte, high Nibble 1st } end; |
对BCD的支持是在FMTBcd单元中,所以要使用BCD函数,则需要引用此单元。
Delphi的BCD函数有:
BcdAdd | 计算两个BCD码的和 |
BcdCompare | 比较两个BCD的大小 |
BcdDivide | BCD数据相除 |
BcdMultiply | BCD数据相乘 |
BcdPrecision | 返回BCD的数据个数。如BCD的123返回值为3,BCD值为9382时返回值为4。 |
BcdScale | 返回BCD码的小数位数 |
BcdSubtract | 两个BCD码相减 |
BCDToCurr | 转换BCD码为Current格式的数据类型 |
BcdToDouble | BCD码转换为Double格式的数据类型 |
BcdToInteger | BCD码转换为Integer格式的数据类型 |
BcdToStr | BCD码转换为字符串 |
BcdToStrF | BCD码转换为带格式控制的字符串 |
CurrToBCD | Current数据类型转换为BCD码 |
DoubleToBcd | Double数据类型转换为BCD码 |
FormatBcd | 格式化BCD码为字符串 |
IntegerToBcd | Integer整数类型转换为BCD码 |
IsBcdNegative | 判断BCD是否为负数 |
NormalizeBcd | 将一个BCD的值根据给定的精度和小数位数转换为另外一个BCD码的值 |
NullBcd | 判断BCD是否为NULL |
StrToBcd | 字符串转换为BCD码 |
TryStrToBcd | 字符串转换为BCD码,转换失败返回给定的默认值 |
二. Currency类型
和SQL SERVER中money类型一模一样,Delphi中Currency类型:
1) 占用8个字节。
2) 总是4位小数。
3) 范围为:-2^63 ~ 2^63-1(-922,337,203,685,477.5808 ~ 922,337,203,685,477.5807)。存储格式相当于总是乘以10000,然后按整数格式保存。
三. BCD字段类型(TBCDField)
现在很多数据库中都有了Decimal和Numeric数据类型,它们可以精确保存浮点类型,可以将Decimal和Numeric类型映射为BCD字段类型。
在BDE的TDatabase控件,有一个EnableBCD选项:
在ADO的TADOQuery也有EnableBCD选项。
EnableBCD选项的用来说明如何处理数值类型(Decimal和Numeric)字段:
1) EnableBCD为TRUE时,数值类型字段映射为TBCDField类。
2) EnableBCD为FALSE时,数值类型字段映射为TFloatField类。
TBCDField定义在DB.pas文件中:
TBCDField = class(TNumericField)
private
FCurrency: Boolean;
FCheckRange: Boolean;
FMinValue: Currency;
FMaxValue: Currency;
FPrecision: Integer;
procedure SetCurrency(Value: Boolean);
procedure SetMaxValue(Value: Currency);
procedure SetMinValue(Value: Currency);
procedure SetPrecision(Value: Integer);
procedure UpdateCheckRange;
protected
class procedure CheckTypeSize(Value: Integer); override;
procedure CopyData(Source, Dest: Pointer); override;
function GetAsBCD: TBcd; override;
function GetAsCurrency: Currency; override;
function GetAsFloat: Double; override;
function GetAsInteger: Longint; override;
function GetAsString: string; override;
function GetAsVariant: Variant; override;
function GetDataSize: Integer; override;
function GetDefaultWidth: Integer; override;
procedure GetText(var Text: string; DisplayText: Boolean); override;
function GetValue(var Value: Currency): Boolean;
procedure SetAsBCD(const Value: TBcd); override;
procedure SetAsCurrency(Value: Currency); override;
procedure SetAsFloat(Value: Double); override;
procedure SetAsInteger(Value: Longint); override;
procedure SetAsString(const Value: string); override;
procedure SetVarValue(const Value: Variant); override;
public
constructor Create(AOwner: TComponent); override;
property Value: Currency read GetAsCurrency write SetAsCurrency;
published
{ Lowercase to avoid name clash with C++ Currency type }
property currency: Boolean read FCurrency write SetCurrency default False;
property MaxValue: Currency read FMaxValue write SetMaxValue;
property MinValue: Currency read FMinValue write SetMinValue;
property Precision: Integer read FPrecision write SetPrecision default 0;
property Size default 4;
end;
|
注意:不是用TBCD来保存的),而Currency固定有且只有4位小数,所以精度超过4位请使用TFloatField(即EnableBCD位FALSE)。
四. 参考文献
- Delphi中对BCD码的直接支持 .