Delphi中BCD和Currency类型

用了这些年的Delphi,竟然对Currency及TBCDField一知半解,下文给了很好的讲解,值得一读。

 一.       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)。

* 精度太高如果使用TFloatField有时发现录入的小数保存后会发生变化,这时还可以选择使用TFMTBCDField来保存数据;

  UniDAC可参考下图设置:

修改EnableFMTBCD属性后需将UniQuery打开刷新一次(双击Active属性2次),最后将字段删除再重新拉进来, 对应的字段就会变成TFMTBCDField类型。

 

  四.       参考文献

  1. Delphi中对BCD码的直接支持 .

http://www.cnblogs.com/ywangzi/archive/2012/11/14/2769823.html

转自: https://www.cnblogs.com/lrl45/p/5135460.html

转载于:https://www.cnblogs.com/railgunman/p/9239466.html

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值