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;}
Q2: Как я могу сделать правильное банковское округление с типом данных Curreny?
Взгляните на функцию System::Round()
, которая использует банковское округление.
Если вы хотите больше контролировать округление, используйте функцию System::Math::RoundTo()
или найдите стороннюю функцию округления.
В StackOverflow есть несколько других вопросов, касающихся округления Currency
, например:
Как заставить тип валюты Delphi постоянно округляться, как в Excel?
округление валюты
(System::Currency
— это оболочка C++Builder для родного типа Delphi Currency
).
person
Remy Lebeau
schedule
25.04.2017
System::Currency
не является частью стандартного C++. Вы случайно не компилируете как C++/CLI вместо C++? - person Algirdas Preidžius   schedule 24.04.2017