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)。
四. 參考文獻
- Delphi中對BCD碼的直接支持 .
http://www.cnblogs.com/ywangzi/archive/2012/11/14/2769823.html