[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 12.42 %package require money 1.0 %money-value [money/ [money 12.42] 10] 1.4 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 \$a adol acent 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 \$a adol acents lassign \$b bdol bcents set cents [expr {\$acents - \$bcents}] if {\$cents < 0} { incr adol -1 set cents [expr {\$cents + 100}] } set dollars [expr {\$adol - \$bdol}] list \$dollars \$cents } proc money* {a integer} { lassign \$a adol acent 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} { lassign \$a adol acent 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]