Is Currency data type really usable?

I read a big value from a database, as a fixed decimal that fits into the Currency data type.
In another situation I have to accept the user input as a similar big number.

In any case I have to convert from String to Currency and this seems not possible without passing from Double and loosing precision.
See the code below:

[code] dim value as string = “123456789012345.1234”

dim c1 as currency = val(value)
dim c2 as currency = ctype(val(value), Currency)
dim v as variant = value
dim c3 as currency = v.currencyValue

// results
// c1 = 123456789012345.1094
// c2 = 123456789012345.1094
// c3 = 123456789012345.1094
[/code]

But the problem is not only with strings. The code below also produce wrong results:

dim c4 as Currency = 123456789012345.1234 // c4 = 123456789012345.1094

Now, what’s the meaning of having a Currency data type if I have to pass from Double to fill it with some value?

Am I overlooking something?

Yes. Try adding a currency type value to a json item. You’ll get a corrupt json string.

the problem seems to be an intermediate conversion to double which only has precision for 15 digits.

[quote=126595:@Massimo Valle]Now, what’s the meaning of having a Currency data type if I have to pass from Double to fill it with some value?

Am I overlooking something?[/quote]

I get the same result. Seems accuracy remains only up to 123456789012.1234.

That is not enough to represent the French national debt or 1,925,300,000,000 € or the US $12.6 trillion national debt precisely to the penny. But at such amounts, who still care about cents ?

Of course, such imprecision would be a problem in Zimbabwe, but am not sure there are really many Xojo users over there …

[quote=126600:@Michel Bujardet]I get the same result. Seems accuracy remains only up to 123456789012.1234.

That is not enough to represent the French national debt or 1,925,300,000,000 € or the US $12.6 trillion national debt precisely to the penny. But at such amounts, who still care about cents ?

Of course, such imprecision would be a problem in Zimbabwe, but am not sure there are really many Xojo users over there …[/quote]

Michel your are underestimating the problem.
First, Is it not said it’s used to store money.
Second, the problem comes when you start doing math with these values.
Third, it fails to achieve exactly the purpose it’s designed for: avoid doubles and rounding errors.

If the Currency datatype has fixed decimal memory representation (as I hope), it needs ways to fill this datatype without passing from double. Either as a constant value or converting to/from a string.

I’ve tested with a couple of trial programs. As @Michel Bujardet stated I’ve found that if you want to use ‘Currency’ without losing digits, the full resolution can have up to 13 whole digits + 4 after the decimal (17 digits total). More than that gives odd (incorrect) results. I believe it’s stored in a 64 bit integer, with an assumed 4 digit ‘decimal’.

[quote=126603:@Massimo Valle]Michel your are underestimating the problem.
First, Is it not said it’s used to store money.
Second, the problem comes when you start doing math with these values.
Third, it fails to achieve exactly the purpose it’s designed for: avoid doubles and rounding errors.

If the Currency datatype has fixed decimal memory representation (as I hope), it needs ways to fill this datatype without passing from double. Either as a constant value or converting to/from a string.[/quote]

I am sorry, my post did not take into account your very real concern. I should not make fun of this issue. Neither the mathematical errors, nor national debts, by the way.

When built in functions fail, creating a new type of variables comes to mind. At first glance, since very large numbers can be represented as strings, additions and subtractions seem fairly possible, but divide and multiplications may prove challenging. Although manual operations as I learned in school half a century ago seem doable through algorithms. Others such as square root, not to mention trigonometric, are too far away in time for me to really remember.

Without reinventing the wheel, maybe there are some classes or plugins doing large number calculation, already ?

It is exactly what is said in the LR http://documentation.xojo.com/index.php/Currency

The LR states 15 digits to the left + 4 to the right of the decimal.
More than 13 is unreliable.

I looked at what is permitted by UInt64 and it allows numbers up to 9,223,372,036,854,775,807. This may sound stupid, but would it not be possible instead of reverting to computerized manual calculation as I thought aloud before, to assemble two UInt64, one for the exponent, the other for the fraction, to attain a superior degree of precision ? And if the fractional part does not require so many digits, to use an integer there ?

Even an integer applied to the fractional part would never create the gross rounding errors.

[quote=126608:@John A Knight, Jr]The LR states 15 digits to the left + 4 to the right of the decimal.
More than 13 is unreliable.[/quote]

Right. I should have said you were right on the money (pun intended) with 64 bits.

Bob Delaney ( delaneyrm.com ) has a ‘Decimal’ plug-in that provides a ‘Decimal’ type with arbitrary size (limited by RAM) if you really need to compute with national debt magnitudes.

This could be of interest :
http://decimal-plugin.apponic.com/mac/

Found through this search where there are more items :

https://duckduckgo.com/?q=realbasic+large+numbers

Edit : John and I found the same plugin at the same time on two different sites :wink:

If millions of digits not required, this works and math does not seem out of reach on two variables :

[code] dim value as string = “923456789012345678.1234”

dim expon as UInt64
dim fract as integer

expon = val(left(value,instr(value,".")))
if instr(value,".") < len(value) then
fract = val(right(value,len(value)-instr(value,".")))
end if

msgbox format(expon,"###,###,###,###,###,###,###,###,###")+"."+format(fract,"####################")[/code]

Thanks to all for the suggestions.
Still the Currency data type is flawed and will report this.

In our last accounting application the client’s smallest value was a penny which made life easy. We used Int64 for all money values and during display we converted it to dollars and cents. It has worked well, so far, but I’m sure it will come back to haunt us when they start collecting sales tax and need to start tracking that 1/3 of a cent.

I’ve been playing around with currency recently I’ve not found it very easy/intuitive to work with. It has the four digits to the right of the decimal. I see no way to force that to two digits unless I do the math myself. Anyone have an ‘easy’ way to do this?

Just use two if you need so.
And when you display it, set the format accordingly.

The good of fixed point data types is you never get the value rounded if you display it to a greater precision. So that if you have 1234.12 you will never get displayed 1234,1199 if you display it with four decimal digits.

Ah, but this an accounting application. Those fractions of a penny are disastrous in calculations when you’re dealing with tens of thousands of sales tax calculations. 0.011 is not the same as 0.01 and will affect totals. The DISPLAY is easy but somewhere I have to convert the .011 to .01 or I risk of getting those inevitable “your app can’t add” emails.

Trust me when I say that accountants will question you about the penny difference.

I have the same problem with accountants (that’s why I opened this thread).

But if you put 0.1 into a Currency property, it will show as 0.1 or 0.10 or at least as 0.1000
Of course if you store 0.11 and try to show it with a single decimal, rounding will occur. But the same guy will argue that penny worth something and you can just trash it.

Filed a report for this: <https://xojo.com/issue/35189>