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;
因為TBCDField使用Currency類型來保存數據(注意:不是用TBCD來保存的),而Currency固定有且只有4位小數,所以精度超過4位請使用TFloatField(即EnableBCD位FALSE)。