Q1: Why does the calculation of the modulus fail when using the "%" operator?
System::Currency operates with a precision of 4 decimal places. Your example expects 2-digit precision instead.
System::Currency maintains its precision without rounding errors by internally multiplying input values by 10000 and then using integer math instead of floating-point math to manipulate values.
When you initialize TaxValue with 1.665, its internal Val member (which is an __int64) is set to (1.665 * 10000) = 16650. Here is what that constructor looks like:
__fastcall Currency(double val) {Val = _roundToInt64(10000 * val);}
When you then perform TaxValue % 100, the % operator is implemented like this:
Currency __fastcall operator %(int rhs) const
{return Currency(static_cast<int>(Val % (10000 * (__int64)rhs))) / 10000;}
The first part creates a temp Currency object that is initialized with an int value of (16650 % (10000 * 100)) = 16650, which gets multiplied by 10000 to 166500000 by the constructor of the temp object:
__fastcall Currency(int val) {Val = 10000*(__int64)val;}
The second part then divides the temp by 10000. The / operator is implemented like this:
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);}
Thus producing a final Currency object whose Val has been set to (166500000 * 10000) / (10000 * 10000) = 16650.
When that final Currency is then assigned to Rest and converted to double, the value is divided by 10000, thus producing 1.665:
__fastcall operator double() const {return ((double)Val) / 10000;}
Q2: How can I do a correct banker's rounding with the Curreny data type?
Have a look at the System::Round() function, which uses banker's rounding.
If you want more control over the rounding, use the System::Math::RoundTo() function, or find a 3rd party rounding function.
There are several other questions on StackOverflow that deal with Currency rounding, for instance:
How to get Delphi Currency Type to Round like Excel all the time?
rounding a currency
(System::Currency is C++Builder's wrapper for Delphi's native Currency type).