有 5 位小数的货币?

Currency with 5 decimal digits?

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

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

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

当我在 Delphi 中使用 double 时,有几个问题,因为它没有固定的小数点。此外,当保存到 ADO 数据库中时,数据库查看器通常会显示一个非常长的数字,因为它的位数太多。此外,似乎存在舍入方法问题,舍入并不总是完成 "away from zero".

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

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

var
  x: Decimal[5,3]

但是这个语法对我无效。我在 Delphi 2007 年工作。

我可以做些什么来获得 5 位固定小数?

最简单的方法是使用变量CurrencyDecimals。 类似的东西:

var
  price: Double;

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

下面是一些使用 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)