## Version 6 of A Money Package

Updated 2008-07-04 10:09:28 by jmn

George Peter Staplin July 3 2008 -- Here is a simple package for handling money without floating point. It may not be ideal for everyone -- yet. Feel free to improve this, and extend this page.

It could probably use a money-precision command for setting the precision of the numbers after the decimal point.

JMN This might be a nice start for the API - but as it stands it's wildly inaccurate.

e.g calculate 10% tax on 19.11

``` %package require money
1.0
%money-value [money/ [money 19.11] 10]
1.1```

The point of a money package should not be so much to avoid floating-point operations at all cost - but to operate at a level where the errors are at a minimum and you choose when and with what method you do your rounding. e.g by using cents or even some fraction of a cent as your basic unit for calculation and storage.

Other languages seem to have pushed towards a Decimal datatype for currency work.

Martyn Smith My simple solution was to do all math using integer cents/centimes values and just to display a ./, in the right place when displaying any values, the integer math is very quick and no rounding problems.

``` #By George Peter Staplin
#Use it, share it, modify it, don't blame me.

package provide money 1.0

proc money value {
lassign [split \$value .] dol cents

set dol [expr {\$dol + (\$cents / 100)}]
set cents [expr {\$cents % 100}]
list \$dol \$cents
}

proc money-value m {
join \$m .
}

proc money-pretty m {
return \\$[join \$m .]
}

proc money+ {a b} {
lassign \$b bdol bcent

set dollars [expr {\$adol + \$bdol}]
set cents [expr {\$acent + \$bcent}]
set dollars [expr {\$dollars + (\$cents / 100)}]
set cents [expr {\$cents % 100}]
list \$dollars \$cents
}

proc money- {a b} {
lassign \$b bdol bcents

set cents [expr {\$acents - \$bcents}]
if {\$cents < 0} {
set cents [expr {\$cents + 100}]
}
set dollars [expr {\$adol - \$bdol}]
list \$dollars \$cents
}

proc money* {a integer} {

set dollars [expr {\$adol * \$integer}]
set cents [expr {(\$acent * \$integer)}]
set dollars [expr {\$dollars + (\$cents / 100)}]
set cents [expr {\$cents % 100}]
list \$dollars \$cents
}

proc money/ {a integer} {
set cents [expr {\$acent / \$integer}]
set dollars [expr {\$adol / \$integer}]
list \$dollars \$cents
}

set cd [money 12.45]
set car [money 3999.99]

puts "CD + CAR [money-value [money+ \$cd \$car]]"

puts [money-value [money* [money+ \$cd \$car] 2]]

puts "44.02 - 12.99: [money-value [money- [money 44.02] [money 12.99]]]"

puts "42.0 / 4: [money-value [money/ [money 42.0] 4]]"

puts "45.5 / 3: [money-value [money/ [money 45.5] 3]]"

puts "42.0 * 42 * 42 = You're rich! = [money-pretty [money* [money* [money 42.0] 42] 42]]"```

Category Currency and Finance