Currency calculation wrong

Just reported via Feedback: <https://xojo.com/issue/53197>

If we do math like this:

dim c as currency = 161.64 dim e as Currency = c * 100 dim d as int64 = c * 100 Break

e is 16164 which is correct, but d is 16163, which is not correct.

Can we make sure that math like this correct?

e.g. internally I would expect that c is 1616400 and multiply by 100 is actually a divide by 100 with conversion to Int64.

Did this test:

Dim c As Currency = 161.64 Dim e As Currency = c * 100 Dim d As Int64 = c * 100 Dim f As Double = c Dim g As Double = c * 100 Dim h As Double = 161.64 Dim i As Int64 = e Break

Of course I don’t know what is going on internally, but it looks like:

Dim d As Int64 = c * 100

first c is changed to the double value (161.639…) then * 100, so the result d is 16163 and i is correct with 16164

Well, it would be good if the compiler could be a bit more clever here.
e.g. use round for double -> int64.

Even better would be if compiler sees that currency is an int64 internally, so it can change *100 to /100 in this conversion.

I agree Christian, I expect this:
See ‘c’ as currency, check that there is an operation, treat the operation as currency, then the final result (as currency) assign it to ‘d’ that is Int64.

Something like:

Dim c As Currency = 161.64 Dim e As Currency = c * 100 Dim d As Int64 = c * 100 // currency, same as 'e'

I guess the currency calculation is not wrong, but the way the calculation is done when assigned to a non currency variable, right?

This works though…

Dim e As Int64 = ctype(c * 100, currency)

and so does:

Dim d as Int64 = e

That probably means that you should do all of your currency calculations using Currency typed variables and then convert to something else.

The problem is that we want to trust in the data types and know you guys have tons of test cases to make sure they work well in all ways.

I think this is the first time I see ‘ctype’ (still lot to learn). Reading about ctype I see this:

Then what Greg posted:

Dim e As Int64 = ctype(c * 100, currency)

Then what an user could expect with c is currency but we are using = to Int64:
a) c considered as Int64 then * 100, result should be 16100, like:

Dim c As Currency = 161.64 Dim d As Int64 = c d = d * 100
or
b) c considered as currency * 100, result converted to Int64, like:

Dim c As Currency = 161.64 Dim e As Currency = c * 100 Dim d As Int64 = e

but in reality we get d = 16163

Dim c As Currency = 161.64 Dim d As Int64 = c * 100

If we use a decimal plugin with this code:

Dim c As Decimal = 161.64 Dim d As Int64 = c * 100
we get d = 16164
as we original expected. My guess is, because the decimal plugin is not a Xojo data type, then Xojo does not convert it to double to do the * 100 calculation and we get the expected result.

After doing some tests and re-reading the ctype notes, I think the problem is with the “implicit conversion”.

Original code:

Dim c As Currency = 161.64 Dim e As Int64 = c * 100

Expected result (using code):

Dim c As Currency = 161.64 Dim e As Int64 = ctype(c * 100, Currency)

Actual result (equal to):

Dim c As Currency = 161.64 Dim e As Int64 = ctype(c * 100, Double)

I expected the implicit conversion to “see” that c is currency and do a currency calculation and not as double.

Edit: I see <https://xojo.com/issue/53197> marked as Verified