Lazarus中文社区

 找回密码
 立即注册(注册审核可向QQ群索取)

QQ登录

只需一步,快速开始

Lazarus IDE and 组件 下载地址版权申明
查看: 4425|回复: 8

ftFloat 可以用做货币类型吗

[复制链接]

该用户从未签到

发表于 2010-11-15 20:55:14 | 显示全部楼层 |阅读模式
听说货币类型用float,double,在计算时会有精度损失。那么下面的这个ftFloat类型,想在数据库中做为货币类型使用,在计算时会有精度损失吗?我也想直接用ftCurrency,可是因为我用的控件不支持ftCurrency啊。但是他支持ftFloat,并且是按下面的代码定义的。

const
  DefaultFieldClasses : Array [TFieldType] of TFieldClass =
    ( { ftUnknown} Tfield,
      { ftString} TStringField,
      { ftSmallint} TSmallIntField,
      { ftInteger} TLongintField,
      { ftWord} TWordField,
      { ftBoolean} TBooleanField,
      { ftFloat} TFloatField,
       ...   

{ TFloatField }

  TFloatField = class(TNumericField)
  private
    FCurrency: Boolean;
    FMaxValue : Double;
    FMinValue : Double;
    FPrecision : Longint;
    procedure SetCurrency(const AValue: Boolean);
  protected
    function GetAsFloat: Double; override;
    function GetAsLongint: Longint; override;
    function GetAsVariant: variant; override;
    function GetAsString: string; override;
    function GetDataSize: Integer; override;
    procedure GetText(var theText: string; ADisplayText: Boolean); override;
    procedure SetAsFloat(AValue: Double); override;
    procedure SetAsLongint(AValue: Longint); override;
    procedure SetAsString(const AValue: string); override;
    procedure SetVarValue(const AValue: Variant); override;
  public
    constructor Create(AOwner: TComponent); override;
    Function CheckRange(AValue : Double) : Boolean;
    property Value: Double read GetAsFloat write SetAsFloat;

  published
    property Currency: Boolean read FCurrency write SetCurrency default False;
    property MaxValue: Double read FMaxValue write FMaxValue;
    property MinValue: Double read FMinValue write FMinValue;
    property Precision: Longint read FPrecision write FPrecision default 15;
  end;



{ TNumericField }
  TNumericField = class(TField)
  Private
    FDisplayFormat : String;
    FEditFormat : String;
  protected
    class procedure CheckTypeSize(AValue: Longint); override;
    procedure RangeError(AValue, Min, Max: Double);
    procedure SetDisplayFormat(const AValue: string);
    procedure SetEditFormat(const AValue: string);
    function GetAsBoolean: Boolean; override;
  public
    constructor Create(AOwner: TComponent); override;
  published
    property Alignment default taRightJustify;
    property DisplayFormat: string read FDisplayFormat write SetDisplayFormat;
    property EditFormat: string read FEditFormat write SetEditFormat;
  end;         

我用的控件,一用ftCurrency就报错!

With memDataSet1 Do
  Begin
    Close;

    FieldDefs.Clear;

    FieldDefs.Add ('Name', ftInteger, 0, True);

    FieldDefs.Add (&#39rice',  ftCurrency, 10, False);

    CreateTable;

    Open;
  End ;              

Fieldtype of Field &quotrice" not supported !
回复

使用道具 举报

该用户从未签到

发表于 2010-11-16 06:41:59 | 显示全部楼层
以小弟來說, 對於開發工具沒有提供的功能,
會試著去測試或找代替方法, 而不是坐在那邊耽心
偶相信這兩個 type 精度是有差異的, 不過
小弟會先自行寫個測試程式測試在自己應用領域中
有沒有影響, 以 POS 來說, 需要計算到小數一位而已
在開發給客戶使用的系統中, 用 ftFloat  到現在三年還沒遇到什麼問題

那篇文章中有句話挺有意思, "分数1/10在二进制系统中没有精确的表示,其道理就如同在十进制系统中无法精确表示1/3一样" , 是否表示就算換用十进制系统思維, 遇到 "飲料買三杯, 一杯免費" 這種 POS 常玩的組合促銷手法中, 折扣計算仍有精度誤差 ??
回复 支持 反对

使用道具 举报

该用户从未签到

 楼主| 发表于 2010-11-16 11:54:03 | 显示全部楼层
楼上的大侠,请问如何修改memdataset源码,使之直接支持ftCurrency? 这样不是更好,因为我要保存小数点后面的至少两位小数,而非只保留一位。谢谢。
回复 支持 反对

使用道具 举报

该用户从未签到

 楼主| 发表于 2010-11-16 12:18:16 | 显示全部楼层
另外,想问下bruce0829大哥,你一直使用lazarus开发数据库应用,给客户用吗?比起delphi开发的程序,他的执行效率慢吗?我怎么觉得lazarus开发的程序,双击后,启动速度比较delphi的慢一点啊。
回复 支持 反对

使用道具 举报

该用户从未签到

发表于 2010-11-16 14:42:31 | 显示全部楼层
Lazarus 才剛學半年
目前還沒有寫出什麼程式給客戶使用

float 處理小數兩位應該是沒問題
一般單筆資料不用擔心這個問題
只怕 SUM 之後產生誤差
如 2.499999999999..  連加 100 次
跟 2.5 連加 100 次
結果會有差異, 但這並不難解決

Lazarus 的確比 Delphi 慢, 在繪圖處理測試時就有見識到
如果您只是在 win32 下開發程式, 建議用 DELPHI 就好
不過大家都說過, Lazarus 的強項在跨平台
回复 支持 反对

使用道具 举报

该用户从未签到

 楼主| 发表于 2010-11-16 14:52:39 | 显示全部楼层
結果會有差異, 但這並不難解決。 怎么解决啊?
回复 支持 反对

使用道具 举报

该用户从未签到

发表于 2010-11-16 15:47:42 | 显示全部楼层
你可以用这里的替代:
http://mantis.freepascal.org/view.php?id=17663

memtable.pp is the memory table component.
回复 支持 反对

使用道具 举报

该用户从未签到

发表于 2010-11-15 22:09:16 | 显示全部楼层
可以啊,我一直这样做,为什么不可以
回复 支持 反对

使用道具 举报

该用户从未签到

 楼主| 发表于 2010-11-16 01:50:49 | 显示全部楼层
看这篇,难道你不担心精度的问题吗?

如果要求精确的答案,请避免使用float和double
http://blog.csdn.net/ForWayfarer/archive/2008/10/10/3052344.aspx
回复 支持 反对

使用道具 举报

*滑块验证:

本版积分规则

QQ|手机版|小黑屋|Lazarus中国|Lazarus中文社区 ( 鄂ICP备16006501号-1 )

GMT+8, 2025-5-3 11:07 , Processed in 0.031066 second(s), 10 queries , Redis On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表