math::exact(3tcl)
π math::exact β Exact Real Arithmetic π
ok so bestie, you've stumbled into math::exact, part of the Tcl Math Library (that's the 3tcl manual, iykyk). Buckle up because this one is genuinely iconic: it does math that is actually exact, not just "exact-ish with more digits". Let's get into it. π¦
β¨ SYNOPSIS β¨
package require Tcl 8.6 9
package require grammar::aycock 1.0
package require math::exact 1.0.2
::math::exact::exactexpr expr
number ref
number unref
number asPrint precision
number asFloat precision
πΈ DESCRIPTION πΈ
okay so the exactexpr command in the math::exact package lets you do exact computations over the computable real numbers. And no, this is not your regular arbitrary-precision situation β bestie, this is a whole different vibe. These are exact. The numbers are represented by algorithms that keep producing successive approximations. π
At the end of a calculation you (the caller, the main character) can ask for a specific precision for the final result, and all the intermediate results get computed to whatever precision is actually necessary to satisfy that request. No more, no less. It's giving efficiency. β¨
π PROCEDURES π
This next one is the primary entry point into the math::exact package. The way that it's the front door of the whole thing.
::math::exact::exactexpr exprβ takes a mathematical expression in Tcl syntax and hands you back an object representing the program that will calculate successive approximations of that expression's value. We're gonna call that result an exact real number. π«Άnumber refβ bumps up the reference count of a given exact real number. (Yes queen, we're doing manual refcounting, stay with me.)number unrefβ drops the reference count of a given exact real number, and destroys the number if the reference count hits zero. πnumber asPrint precisionβ formats the given number for printing at the specified precision. (Howprecisiongets interpreted? Scroll down, we got you.) Numbers that are known to be rational get formatted as fractions. πnumber asFloat precisionβ formats the given number for printing at the specified precision. (Same deal withprecision, see below.) Every single number gets formatted in floating-pointEformat.
π PARAMETERS π
exprβ the expression to evaluate. The syntax for expressions is the same as it is in Tcl, but the set of operations is smaller. Head to Expressions below for the details.numberβ the object returned by an earlier invocation ofmath::exact::exactexpr.precisionβ the requested 'precision' of the result. So basically, precision is (approximately) the absolute value of the binary exponent plus the number of bits of the binary significand. For instance, to return results to IEEE-754 double precision, you need 56 bits plus the exponent. Let's break it down because this is lowkey the whole game:- Numbers between 1/2 and 2 β precision of 57
- Numbers between 1/4 and 1/2, or between 2 and 4 β 58
- Numbers between 1/8 and 1/4, or between 4 and 8 β 59
- and so on, forever, slay. β
π EXPRESSIONS π
The math::exact::exactexpr command accepts expressions in a subset of Tcl's syntax. Here's what you're allowed to use in an expression:
- Decimal integers. π’
- Variable references with the dollar sign (
$). The value of the variable must be the result of another call tomath::exact::exactexpr. The reference count of that value gets increased by one for each position at which it appears in the expression. (Yes, every position. Count them. π) - The exponentiation operator (
**). - Unary plus (
+) and minus (-) operators. - Multiplication (
*) and division (/) operators. - Parentheses used for grouping.
- Functions. See Functions below for what's available.
π§ FUNCTIONS π§
These are the functions you can use inside exact real expressions. All of them, no skips:
acos(x)β the inverse cosine of x. Result comes out in radians. The absolute value of x must be less than 1.acosh(x)β the inverse hyperbolic cosine of x. x must be greater than 1.asin(x)β the inverse sine of x. Result comes out in radians. The absolute value of x must be less than 1.asinh(x)β the inverse hyperbolic sine of x.atan(x)β the inverse tangent of x. Result comes out in radians.atanh(x)β the inverse hyperbolic tangent of x. The absolute value of x must be less than 1.cos(x)β the cosine of x. x is expressed in radians.cosh(x)β the hyperbolic cosine of x.e()β the base of the natural logarithms =2.71828...exp(x)β the exponential function of x.log(x)β the natural logarithm of x. x must be positive.pi()β the value of pi =3.15159...sin(x)β the sine of x. x is expressed in radians.sinh(x)β the hyperbolic sine of x.sqrt(x)β the square root of x. x must be positive.tan(x)β the tangent of x. x is expressed in radians.tanh(x)β the hyperbolic tangent of x.
π SUMMARY π
The math::exact::exactexpr command gives you a system that performs exact arithmetic over computable real numbers, representing those numbers as algorithms for successive approximation. Here's an example that implements the high-school quadratic formula. It's giving nostalgia but make it rigorous. π
namespace import math::exact::exactexpr
proc exactquad {a b c} {
set d [[exactexpr {sqrt($b*$b - 4*$a*$c)}] ref]
set r0 [[exactexpr {(-$b - $d) / (2 * $a)}] ref]
set r1 [[exactexpr {(-$b + $d) / (2 * $a)}] ref]
$d unref
return [list $r0 $r1]
}
set a [[exactexpr 1] ref]
set b [[exactexpr 200] ref]
set c [[exactexpr {(-3/2) * 10**-12}] ref]
lassign [exactquad $a $b $c] r0 r1
$a unref; $b unref; $c unref
puts [list [$r0 asFloat 70] [$r1 asFloat 110]]
$r0 unref; $r1 unref
And the program prints the result:
-2.000000000000000075e2 7.499999999999999719e-15
Now here's the tea: if IEEE-754 floating point had been used, a catastrophic roundoff error would have handed you a smaller root that is a factor of two too high:
-200.0 1.4210854715202004e-14
The invocations of exactexpr should be fairly self-explanatory. The other commands of note are ref and unref. And fr fr, it is necessary for the caller to keep track of references to exact expressions β call ref every single time an exact expression gets stored in a variable, and unref every time that variable goes out of scope or gets overwritten. Don't be sloppy, the refcounts will know. π
The asFloat method emits decimal digits for as long as the requested precision supports them. It terminates when the requested precision yields an uncertainty of more than one unit in the least significant digit. π―
β CATEGORY β
Mathematics
π COPYRIGHT π
Copyright (c) 2015 Kevin B. Kenny <kennykb@acm.org> Redistribution permitted under the terms of the Open Publication License <http://www.opencontent.org/openpub/>
ok bestie that's the whole page, you ate it, periodt. π«Άβ¨ this was math::exact, version 1.0.2, from the tcllib collection, and this manual page is dated 1.0.2 too β go forth and compute exactly, no cap π
ππ¦
π¦ where this page comes from
- debian trixie: tcllib 2.0+dfsg-4 Β· Tcl
- ubuntu questing: tcllib 2.0+dfsg-4
- ubuntu resolute: tcllib 2.0+dfsg-5 Β· Tcl
- ubuntu stonking: tcllib 2.0+dfsg-6 Β· Tcl
- Copyright (c) 2015 Kevin B\&. Kenny <kennykb@acm\&.org>
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms