MoneyStringToCents() and CentsToMoneyString()

Share your advanced PureBasic knowledge/code with the community.
firace
Addict
Addict
Posts: 903
Joined: Wed Nov 09, 2011 8:58 am

MoneyStringToCents() and CentsToMoneyString()

Post by firace »

Here are two short procedures that I have found useful when working with money values, lately.
Why they are needed: As you may know, using floats is a very bad idea (in all languages) when dealing with money.
Careful: Not thoroughly tested. Comments and bug reports welcome :)

EDIT1: code updated with Stargate's bugfix

Code: Select all

Procedure.q MoneyStringToCents(amount.s, howmanydecimals=2)  
  WholePart.s    = StringField(amount, 1, ".")
  DecimalsPart.s = StringField(amount, 2, ".")
  DecimalsPart  = LSet(DecimalsPart, howmanydecimals, "0")
  ProcedureReturn Val(WholePart + DecimalsPart)
EndProcedure   

;Debug ValF("3.00028224")
Debug MoneyStringToCents("3.00028224")
Debug MoneyStringToCents("324")
Debug MoneyStringToCents("1000000000000002")
Debug "---"

Procedure.s CentsToMoneyString(amount.q, howmanydecimals=2)  
  DecimalsPart.s = Right(Str(amount), howmanydecimals)
  If Len(DecimalsPart) < howmanydecimals : DecimalsPart = RSet(DecimalsPart, howmanydecimals, "0") : EndIf 
  WholePart.s = "0" : If Len(Str(amount)) > howmanydecimals : WholePart.s = Left(Str(amount), Len(Str(amount)) - howmanydecimals) : EndIf 
  result.s = WholePart + "." + DecimalsPart
  ProcedureReturn result.s 
EndProcedure 

Debug centsToMoneyString(2245124)
Debug centsToMoneyString(38224)
Debug centsToMoneyString(5)
Debug centsToMoneyString(400)  ;; €4.00
Last edited by firace on Sun Nov 14, 2021 10:56 am, edited 1 time in total.
User avatar
STARGÅTE
Addict
Addict
Posts: 2088
Joined: Thu Jan 10, 2008 1:30 pm
Location: Germany, Glienicke
Contact:

Re: MoneyStringToCents() and CentsToMoneyString()

Post by STARGÅTE »

firace wrote: Sun Nov 14, 2021 9:27 am Why they are needed: As you may know, using floats is a very bad idea (in all languages) when dealing with money.
This is correct. However, you are currently also working with floats.
The function Pow() give a float/double as result. Meaning, the line "Val(WholePart) * Pow(10, howmanydecimals) + Val(DecimalsPart)" is a double.

Such calculation can result in wrong results:

Code: Select all

Debug MoneyStringToCents("1000000000000002")
100000000000000192
Here is my suggestion for correction without floats:

Code: Select all

  ProcedureReturn Val(WholePart + DecimalsPart)
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Lizard - Script language for symbolic calculations and moreTypeface - Sprite-based font include/module
firace
Addict
Addict
Posts: 903
Joined: Wed Nov 09, 2011 8:58 am

Re: MoneyStringToCents() and CentsToMoneyString()

Post by firace »

Good catch! Many thanks for your feedback and bugfix. I have updated the code accordingly.
User avatar
Bisonte
Addict
Addict
Posts: 1232
Joined: Tue Oct 09, 2007 2:15 am

Re: MoneyStringToCents() and CentsToMoneyString()

Post by Bisonte »

I do not use a conversion in that sense. I store the number in the smallest unit (in this case cent). So it is also much better to calculate (eg budget books) and to display the value is simply converted into a string and provided with a comma in the right place ;)
PureBasic 6.10 LTS (Windows x86/x64) | Windows10 Pro x64 | Asus TUF X570 Gaming Plus | R9 5900X | 64GB RAM | GeForce RTX 3080 TI iChill X4 | HAF XF Evo | build by vannicom​​
English is not my native language... (I often use DeepL to translate my texts.)
Post Reply