货币有5位小数?

时间:2016-01-15 09:33:12

标签: delphi precision floating-accuracy

我需要将以下C#代码翻译成Delphi:

decimal XYZ = decimal.Round(dataset123.XYZ, 5, MidpointRounding.AwayFromZero);

结果将保存到MSSQL数据库的float字段中。

当我在Delphi中使用double时,有几个问题,因为它没有固定的小数。此外,当保存到ADO数据库中时,数据库查看器通常会显示一个非常长的数字,因为它的位数太多。此外,似乎存在舍入方法问题,其中舍入并非总是“远离零”。

我想解决目前最严重的问题。我需要 5位数货币,但Delphi只有4位数据类型currency。拥有5位数值是此类项目/业务流程的重要要求。

在一些互联网资源中,我读到人们谈论这样的代码:

var
  x: Decimal[5,3]

但这种语法对我无效。我使用Delphi 2007。

我能做些什么来获得一个5位数的固定小数?

2 个答案:

答案 0 :(得分:1)

以下是一些使用David Heffernan的建议向您展示如何入门的代码:

unit UnitMyCurrency;

interface

uses
  System.SysUtils;

type
  TMyCurrency = record
    Value : int64;

    class operator implicit( pValue : integer ) : TMyCurrency;
    class operator implicit( pValue : single ) : TMyCurrency;
    class operator implicit( pValue : TMyCurrency ) : single;

    class operator Add( p1 : TMyCurrency; p2 : TMyCurrency ) : TMyCurrency;
    class operator Subtract( p1 : TMyCurrency; p2 : TMyCurrency ) : TMyCurrency;

    class operator NotEqual( p1 : TMyCurrency; p2 : single ) : boolean;
  const
    cFactor = 100000;
  end;

implementation

{ TMyCurrency }

class operator TMyCurrency.implicit(pValue: integer): TMyCurrency;
begin
  Result := pValue * cFactor;
end;

class operator TMyCurrency.implicit(pValue: single): TMyCurrency;
begin
  Result := round( pValue * cFactor);
end;

class operator TMyCurrency.Add(p1, p2: TMyCurrency): TMyCurrency;
begin
  Result := TMyCurrency( p1.Value + p2.Value );
end;

class operator TMyCurrency.implicit(pValue: TMyCurrency): single;
begin
  Result := pValue.Value / cFactor;
end;

class operator TMyCurrency.NotEqual(p1: TMyCurrency; p2: single): boolean;
begin
  Result := TMyCurrency( p2 ).Value <> p1.Value;
end;

class operator TMyCurrency.Subtract(p1, p2: TMyCurrency): TMyCurrency;
begin
  Result.Value := p1.Value - p2.Value;
end;

procedure Test;
var
  v1, v2, v3 : TMyCurrency;
begin
  v1 := 5.12345;
  v2 := 6.00000;
  if (v1 + v2 ) <> 11.12345  then
  begin
    raise Exception.Create('Error Message');
  end;
end;

end.

显然它并不完整,但是一旦完成,您将拥有一个新类型,可以满足您的需要,并且您可以完全控制。

以下显示了如何使用重载运算符。它适用于西雅图,但自2007年以来没有任何变化。

http://docwiki.embarcadero.com/RADStudio/en/Operator_Overloading_(Delphi)

答案 1 :(得分:-4)

简单的方法是使用变量CurrencyDecimals。 这样的事情:

var
  price: Double;

begin
  price:= 1234.56789;
  CurrencyDecimals := 5;
  ShowMessage('Price = '+Format('%m', [price]));
end;