System :: Currency和C ++ Builder

时间:2017-04-24 15:19:43

标签: c++ c++builder currency

我正在使用Embarcadero C ++ Builder XE10构建一个执行一些货币计算的应用程序。

在尝试使用System :: Currency数据类型时,我遇到了一些问题。

Q1:当使用"%"时,为什么模数的计算失败?操作

System::Currency TaxValue = 1.665;
System::Currency Rest = 0;

// Correct result: Rest will be 0.005 when converted to double
Rest = TaxValue - ( TaxValue / 100 * 100 );

// Incorrect result: Rest is the same as TaxValue
Rest = TaxValue % 100;
  

编辑:我完全被调试器的输出所愚弄了   System :: Currency的值显示在其整数表示中   到10.000。

     

我真正希望看到的是:

Rest = (TaxValue * 10000) % 100;
     

==>现在休息是50,这正是我的预期。

Q2:如何使用Curreny数据类型对正确的银行家进行四舍五入?

示例:

1.664 => 1.66
1.665 => 1.67
1.666 => 1.67

赫维希

1 个答案:

答案 0 :(得分:1)

  

Q1:使用“%”运算符时,为什么模数计算失败?

System::Currency以4位小数的精度运算。您的示例需要2位精度。

System::Currency通过在内部将输入值乘以10000然后使用整数数学而不是浮点数学来操纵值来保持其精度而不会舍入错误。

使用TaxValue初始化1.665时,其内部Val成员(__int64)设置为(1.665 * 10000) = 16650。这是构造函数的样子:

__fastcall Currency(double val) {Val = _roundToInt64(10000 * val);}

当您执行TaxValue % 100时,%运算符的实现方式如下:

Currency __fastcall operator %(int rhs) const
{return Currency(static_cast<int>(Val % (10000 * (__int64)rhs))) / 10000;}

第一部分创建一个临时Currency对象,该对象初始化为int(16650 % (10000 * 100)) = 16650,由10000乘以166500000__fastcall Currency(int val) {Val = 10000*(__int64)val;} 临时对象的构造函数:

10000

然后第二部分将温度除以/Currency& __fastcall operator /=(const Currency& rhs) {Val *= 10000; Val /= rhs.Val; return *this;} Currency __fastcall operator /(int rhs) const {Currency tmp(*this); return tmp /= Currency(rhs);} 运算符的实现方式如下:

Currency

从而生成Val已设置为(166500000 * 10000) / (10000 * 10000) = 16650的最终Currency对象。

当最终Rest被分配到double并转换为10000时,该值除以1.665,从而产生__fastcall operator double() const {return ((double)Val) / 10000;}

System::Round()
  

Q2:如何使用Curreny数据类型对正确的银行家进行舍入?

查看使用银行家舍入的System::Math::RoundTo()函数。

如果您想要更好地控制舍入,请使用Currency功能,或找到第三方舍入功能。

StackOverflow还有其他一些问题涉及System::Currency舍入,例如:

How to get Delphi Currency Type to Round like Excel all the time?

rounding a currency

Currency是C ++ Builder的Delphi本地git show -s 类型的包装器。)