Mpexpr

 What: mpexpr
 Where: ftp://ftp.procplace.com/pub/tcl/sorted/math/Mpexpr-1.0/1.0/  
        http://www.nyx.net/%7Etpoindex/tcl.html  
 Description: Tcl 7.6/8.0 extension (adding mpexpr and mpformat) that
        supports multiple precision math for Tcl.
        Tested on Solaris and Linux and a Windows port has begun.
        Currently at version 1.0.
 Updated: 09/2000
 Contact: mailto:[email protected]   (Tom Poindexter)

If compiling and adding mpexpr to your tcl environment sounds too much like work and you happen to be running Linux or Unix, check out Bignums Fast and Dirty.


TC - Mpexpr is now being hosted at SourceForge: http://mpexpr.sf.net/


TR Mpexpr (Version 1.1) does only compile properly until Tcl 8.3. After the CONSTification [L1 ] which took place for Tcl 8.4 the compiling returns with an error. You can, however, work around this problem without changing the source code of Mpexpr. Just run the configure script first, then edit the resulting Makefile. In the line saying

  TCL_SHLIB_CFLAGS  = -fPIC

just add another entry to make the line look lke this:

  TCL_SHLIB_CFLAGS  = -fPIC -DUSE_NON_CONST

You can then compile properly and get the extension running for Tcl 8.4

(Tested on Linux only)


A note of caution: It is not always a good idea to just replace the original expr command by mpexpr like so:

 package require Mpexpr
 interp alias {} expr {} mpexpr

This is dangerous because the mpexpr args have not the exact same syntax as the original expr command. For example wide is missing. Also, it can interfere with Tk. The panedwindow from Tk 8.4 will throw an error when trying to move the sash, if the above alias is used ... so just in case, be cautious!


LV Does Mpexpr provide any functionality not included in the Tcl 8.5 larger number support? Just curious whether this code will evolve or whether it will no longer be needed or what.

AM Tcl 8.5 adds support for large integers, but not as far as I know for arbitrary-precision reals. So that is where this package will still be useful.

escargo 6 Dec 2005 - Would this package be faster for multiprecision arithmetic as needed for the Programming Language Shootout? [L2 ]

AM Sure, if you compare it to the Tcl-only solution in Tcllib. Whether it is faster than the library incorporated in Tcl 8.5, I do not know.

escargo 8 Dec 2005 - Somebody tried to use this package for the Shootout, but it wasn't available on the host system so it got an error and bombed out. Thanks for trying.


During Feb, 2002, Gerald Lester posted some basic Tcl code to news:comp.lang.tcl implementing version 0.1 of a Tcl script level package to perform packed decimal math.

   package provide packedDecimal 0.1
   
   namespace eval packedDecimal {
       namespace export add subtract multiply divide setDecimals
   
       variable decimals 2
       variable formatString {%d.%2.2d}
       variable carry 100
   }
   
   proc packedDecimal::add {a b} {
       variable decimals
       variable formatString
   
       scan $a %d.%d a1 a2
       scan $b %d.%d b1 b2
       incr a2 $b2
       if {[string length $a2] > $decimals} then {
           incr a1 1
           set a2 [string range $a2 1 end]
       }
       incr a1 $b1
       return [format $formatString $a1 $a2]
   }
   
   proc packedDecimal::subtract {a b} {
       variable decimals
       variable formatString
       variable carry
   
       scan $a %d.%d a1 a2
       scan $b %d.%d b1 b2
       incr a2 -$b2
       if {$a2 < 0} then {
           incr b1 1
           set a2 [expr {$carry + $a2}]
       }
       incr a1 -$b1
       return [format $formatString $a1 $a2]
   }
   
   proc packedDecimal::multiple {a b} {
       variable decimals
       variable formatString
   
       return -code error {Sorry, Multiple is not yet implemented!}
   }
   
   proc packedDecimal::divide {a b} {
       variable decimals
       variable formatString
   
       return -code error {Sorry, Divide is not yet implemented!}
   }
   
   proc packedDecimal::setDecimals {a} {
       variable decimals
       variable formatString
       variable carry 100
   
       set formatString [format {%%d.%%%d.%dd} $a $a]
       set decimals $a
       set carry [format "1%${a}.${a}d" 0]
       return;
   }
   
   proc packedDecimal::getDecimals {} {
       variable decimals
   
       return $decimals
   }