With these years of Delphi, unexpectedly to currency and Tbcdfield smattering, the following gave a very good explanation, it is worth reading.
1. BCD type
BCD is binary-coded Decimal? In Delphi, the BCD field type can precisely hold floating-point data types.
The data type of the BCD code supported by Delphi is named TBCD, which is defined as follows:
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
The support for BCD is in the Fmtbcd cell, so to use the BCD function, you need to reference this cell.
The BCD functions of Delphi are:
Bcdadd |
Calculates the and of two BCD codes |
Bcdcompare |
Compare the size of two BCD |
Bcddivide |
Dividing BCD data |
Bcdmultiply |
BCD Data multiplication |
Bcdprecision |
Returns the number of data for the BCD. A value of 123, such as the BCD return value of 3,BCD value 9382, is 4. |
Bcdscale |
Returns the number of decimal digits of the BCD code |
Bcdsubtract |
Two BCD code subtraction |
Bcdtocurr |
Convert the BCD code to the current format data type |
Bcdtodouble |
Convert BCD code to a double-formatted data type |
Bcdtointeger |
BCD code converted to the data type in integer format |
Bcdtostr |
Convert BCD code to string |
Bcdtostrf |
BCD code converted to a string with formatting control |
Currtobcd |
Current data type converted to BCD code |
Doubletobcd |
Double data type conversion to BCD code |
Formatbcd |
Format the BCD code as a string |
Integertobcd |
Integer integer type converted to BCD code |
Isbcdnegative |
Determine if the BCD is negative |
Normalizebcd |
Converts the value of one BCD to the value of a different BCD code based on the given precision and number of decimal digits |
Nullbcd |
Determine if the BCD is null |
Strtobcd |
Convert string to BCD code |
Trystrtobcd |
Convert string to BCD code, conversion failure returns the given default value |
2. Currency type
Identical to the money type in SQL Server, the currency type in Delphi:
1) occupies 8 bytes.
2) Always 4 decimal places.
3) Range: -2^63 ~ 2^63-1 ( -922,337,203,685,477.5808 ~ 922,337,203,685,477.5807). the storage format is equivalent to always multiplying by 10000 and then saving in integer format.
3. BCD field type (tbcdfield)
The decimal and numeric data types are now available in many databases, they can precisely hold floating-point types, and decimal and numeric types can be mapped to BCD field types.
In the tdatabase control of BDE, there is a ENABLEBCD option:
The tadoquery of ADO also has the ENABLEBCD option.
The ENABLEBCD option is used to describe how to handle numeric types (decimal and numeric) fields:
1) When ENABLEBCD is true, the numeric Type field is mapped to the Tbcdfield class.
2) When ENABLEBCD is false, the numeric type field is mapped to the Tfloatfield class.
Tbcdfield is defined in the Db.pas file:
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;
Because Tbcdfield uses the currency type to hold the data (note: Not saved with TBCD), and currency is fixed with only 4 decimal places, the accuracy exceeds 4 bits using Tfloatfield (that is, ENABLEBCD bit false).
4. Reference Documents
- Direct support for BCD code in Delphi.
Http://www.cnblogs.com/ywangzi/archive/2012/11/14/2769823.html
BCD and currency types in Delphi