Android Question Working with Money

Stichler

Active Member
Licensed User
Hello all,

I have a simple program for tracking our money, but can't seem to get the decimals under control. I have a variable named money as a double but need to get hose darn decimal points down to 2 n ot the current amount i get. How does one go about making $123.77 instead of 123.772736362627278, and still have accurate math when adding and subtracting from?
 

JordiCP

Expert
Licensed User
Longtime User
I would not use doubles, and instead work internally with integers representing cents, so it will always be exact.
Conversion to Euros with 2 decimal places would then be immediate when you need to show them on screen.
 
Upvote 0

moster67

Expert
Licensed User
Longtime User
I would not use doubles, and instead work internally with integers representing cents, so it will always be exact.
Conversion to Euros with 2 decimal places would then be immediate when you need to show them on screen.
This is the way I was suggested to do when dealing with money.
 
Upvote 0

Sandman

Expert
Licensed User
Longtime User
I would not use doubles, and instead work internally with integers representing cents, so it will always be exact.

Correct. I've never worked with bank systems, but I've discussed this with someone who has. And apparently banks always keep the left side of the decimal as one integer, and the right side of the decimal as another integer. It's super important to never, ever have any issues due to imperfect math or unwanted rounding.

So that would be my recommendation also, go for two integer fields if you need it to be accurate.
 
Upvote 0

keirS

Well-Known Member
Licensed User
Longtime User

As @OliverA posted there is a library to already do this. It implements the Java BigDecimal classes. No point in reinventing the wheel.
 
Upvote 0

udg

Expert
Licensed User
Longtime User
Using a single integer, if amounts are in the proper range, you could multiply by 100 before storing and divide by 100 when reading back, then use NumberFormat2 to show two decimal places.
B4X:
'$123.77
mymoney = 123.55 * 100 --> 12355             'this will be the value in your DB/permanent storage
'add 22 cents
readytostore = mymoney + 22 --> 12377       'no rounding
'1. store the number on DB as an integer (12377)
'2. read back the number from the DB and show it
backfromstore = 12377 / 100 --> 123.77   'pass this one to NumberFormat to display
 
Upvote 0

Semen Matusovskiy

Well-Known Member
Licensed User
Suppose a bank charges 0.1 percent per month during 3 monthes. A client expects (initial contribution) * 1,001 * 1,001 * 1,001.
If to use double, final sum will be the same as in calculator. But if to use integers you will round to 1 cent every month.

Of course, nobody worry about 1 cent. But anyway for which purpose to confuse clients ?
 
Upvote 0

udg

Expert
Licensed User
Longtime User
Suppose a bank charges 0.1 percent per month during 3 monthes. A client expects (initial contribution) * 1,001 * 1,001 * 1,001.
Shoudn't you multiply by 1000 and divide by 1000 in that case? After all you are showing three significant decimal places, no more two as for the OP request.
I anyway agree that this trick is applicable in some circumstances and not in others
 
Upvote 0

npsonic

Active Member
Licensed User
I would not use doubles, and instead work internally with integers representing cents, so it will always be exact.
Conversion to Euros with 2 decimal places would then be immediate when you need to show them on screen.
I must agree with Jordi decimals shouldn't be used with money. It would be much more practical to create for ex. Type money that holds the exact value in two different integers.
 
Upvote 0

OliverA

Expert
Licensed User
Longtime User
it's just a link with zero added information.
Because I hate repeating what is in the link? Would this help, even though I'm just verbatim quoting the link?
 
Upvote 0

Sandman

Expert
Licensed User
Longtime User
Because I hate repeating what is in the link?

No, because you made zero effort in explaining why it was relevant. That's fine, that's your decision. However, if you show no effort I will not waste a click on it to investigate for you.


Would this help, even though I'm just verbatim quoting the link?

Yes, that's an improvement. Even better would be to simply write something like "It's meant for financial computations", which would add a lot of value to the link.

Just reading the actual url I interpreted it to be something scientific that one would use when one need computations with many more decimal places than one usually require. Which isn't really what we were talking about, representing money as two integers.
 
Upvote 0

Star-Dust

Expert
Licensed User
Longtime User
I would not use doubles, and instead work internally with integers representing cents, so it will always be exact.
Conversion to Euros with 2 decimal places would then be immediate when you need to show them on screen.
I have already distributed an App that manages the personal portfolio and the first cash desk.
I used the Double with a sub that corrected the errors generated by the floating point. The thing is really complex and at the closing of cash every six months, the cash team of 1 cent.

The @JordiCP solution is the least cumbersome one. I have adopted it in subsequent versions.
 
Last edited:
Upvote 0

OliverA

Expert
Licensed User
Longtime User
BigDecimal can be a solution but... B4X?
@agraham's BigNumber library (https://www.b4x.com/android/forum/threads/bignumbers-library.9540/#content) should work for B4J. As for B4i, see https://www.b4x.com/android/forum/threads/class-decimalnumber-similar-to-b4a-bignumber.79332/. Not 100% cross platform, but the ability to use arbitrary-precision decimal numbers on B4A/B4J/B4i platforms is there.
simply write something like "It's meant for financial computations
financial computations
It's right there in the second sentence of the link. BTW, me posting the link means that I did do the research for you. Why else would I post the link? That did take my time and effort to find. It just happens that the opening paragraph of that link pretty much explains everything. Still perplexed about the whole I did not spend time on the solution thing though.
 
Upvote 0

JordiCP

Expert
Licensed User
Longtime User
It is turning into an interesting discussion because it depends very much on the premises that each one has assumed to be true

If (as I assumed), the app must deal with real cash adding and substracting, for instance to keep track of home expenses, definitely taking the base internal unit to be the same as physic currency (cents) will make things simpler from the start. Using doubles with math imprecissions and having to use an external library to deal with those, will work anyway, but is less portable and unnecessary.
I have deployed closed-loop prepaid systems with RFID cards, embedded systems and PC programs taking this approach at design, and terribly simplified things.

Sure! Totally agree, if these are the premises
 
Upvote 0
Cookies are required to use this site. You must accept them to continue using the site. Learn more…