math::bigfloat(n) 1.1 "Math"
math::bigfloat - Arbitrary precision floating-point numbers
package require Tcl ?8.4?
package require math::bigfloat ?1.1?
The bigfloat package provides arbitrary precision floating-point math
capabilities to the Tcl language.
By convention, we will talk about the numbers treated in this library as :
- BigFloat for floating-point numbers of arbitrary length
- BigInt for arbitrary length signed integers
BigFloats are internally represented at Tcl lists: this
package provides a set of procedures operating against
the internal representation in order to :
-
perform math operations on either BigFloats or BigInts.
-
convert BigFloats and BigInts from the internal representation to a string, and vice versa.
- fromstr string ?trailingZeros?
-
Convert string into a BigFloat. Its precision
is at least the number of digits provided by string.
trailingZeros - the number of zeros to append at the end of the floating-point number
to get more precision from the string. When applied on an integer, it multiplies
the string integer by 10 at the trailingZerosth power.
|
set x [fromstr -1.000000]
set y [fromstr 2000e30]
# x and y are BigFloats : the first string contained a dot, and the second an e sign
set m [fromstr 1000]
set n [fromstr -39]
# m and n are BigInts because the original string contained neither a dot nor an e sign
# negative BigInts are supported
|
The string's last digit is considered by the procedure to be true at +/-1.
For example, 0.1 is a number between 0.0 and 0.2. 0.10 is between 0.09 and 0.11, and so on.
So, when you mean 1.0, you may have to write 1.000000 to get enough precision.
For example :
|
set x [fromstr 1.0000000000]
# the next line does the same, but smarter
set y [fromstr 1. 10]
# the next line set a BigInt equal to 1
set n [fromstr 1]
# the next line returns 10^10 as a BigInt
set n [fromstr 1 10]
|
- tostr number
-
Returns a string form of a BigFloat, in which all digits are exacts,
or the string form of a BigInt if number is not a BigFloat.
- todouble number
-
Returns a double, that may be used in expr,
from a BigFloat.
- isInt number
-
Returns 1 if number is a BigInt, 0 if it is a BigFloat.
- lshift integer ?exponent?
-
Returns the BigInt integer shifted to the left by exponent digits.
exponent's default value is 1.
- rshift integer ?exponent?
-
Returns the BigInt integer shifted to the right by exponent digits.
exponent's default value is 1.
- roundshift integer ?exponent?
-
Returns the BigInt integer shifted to the right and rounded, by exponent digits.
exponent's default value is 1.
- add x y
-
- sub x y
-
- mul x y
-
Return the sum, difference and product of x by y.
x - may be either a BigFloat or a BigInt
y - may be either a BigFloat or a BigInt
- div x y
-
- mod x y
-
Return the quotient and the rest of x divided by y.
Each argument can be either a BigFloat or a BigInt, but you cannot divide a BigInt by a BigFloat
Divide by zero throws an error.
- abs x
-
Returns the absolute value of x
- opp x
-
Returns the opposite of x
- pow x n
-
Returns x taken to the nth power.
It only works if n is a BigInt.
x might be a BigFloat or a BigInt.
- isnull x
-
Returns 1 if x is :
- a BigFloat close enough to zero to raise "divide by zero".
- a BigInt equal to 0.
- equal x y
-
Returns 1 if x and y are equal, 0 elsewhere.
- compare x y
-
Returns 0 if both BigFloat arguments are equal,
1 if x is greater than y,
and -1 if x is lower than y.
You might compare two BigFloats or two BigInts, but not a BigInt to a BigFloat.
- sqrt x
-
- log x
-
- exp x
-
- cos x
-
- sin x
-
- tan x
-
- cotan x
-
- acos x
-
- asin x
-
- atan x
-
- cosh x
-
- sinh x
-
- tanh x
-
The above functions return, respectively, the following :
square root, logarithm, exponential, cosinus, sinus,
tangent, cotangent, arccosinus, arcsinus, arctangent, hyperbolic
cosinus, hyperbolic sinus, hyperbolic tangent, of the BigFloat x.
- pi n
-
Returns a BigFloat representing the Pi constant with n digits after the dot.
n may be either a simple string, or a BigInt.
- rad2deg radians
-
- deg2rad degrees
-
radians - angle expressed in radians (BigFloat)
degrees - angle expressed in degrees (BigFloat)
Convert an angle from radians to degrees, and vice-versa.
- round x
-
- ceil x
-
- floor x
-
The above functions return the x BigFloat,
rounded like with the same mathematical function in expr,
but returns a BigInt.
Now you may ask this question : What precision am I going to get after calling add, sub, mul or div?
When you set a number from the string representation, say
, we have to see that this number is internally
1.23 (+/- 10^-3).
Let us add two numbers :
|
1.23(+/- 10^-3) + 2.34(+/- 10^-3) = 3.57(+/- 2*10^-3)
set b [fromstr 2.340]
puts [tostr [add $a $b]]
# the result is : 3.57
|
As you can see, the uncertainty of the sum is the sum of both uncertainties of the operands.
The same principle applies to substraction : the uncertainty of the difference is the sum of the
uncertainties of the operands.
But when adding or substracting a BigInt to a BigFloat, and vice-versa, the uncertainty of the
result is exactly the one of the entry. So it is likely to keep integers as BigInt and not to
convert them to BigFloats. The uncertainty is also kept unchanged when multiplying or dividing
a BigFloat by a BigInt.
Let us call 'relative uncertainty' the percentage of uncertainty, i.e. the uncertainty divided by the
value of the number. For example,
|
set x [fromstr 1.000]
# x has a relative uncertainty of 0.1%
|
For multiplication and division, the relative uncertainties of the product
or the quotient, is the sum of the relative uncertainties of the operands.
For most analysis functions (cosinus, square root, logarithm, etc.), determining the precision
of the result is difficult. It seems however that in many cases, the loss of precision in the result
is of one or two digits.
There are some exceptions : for example,
|
tostr [exp [fromstr 100.0 10]]
# returns : 2.688117142e+43 which has only 10 digits of precision, although the entry
# has 13 digits of precision.
|
How do conversions work with precision ?
- When a number is converted from string, the internal representation keep the uncertainty
as 1 to the exponent of the last digit.
- During computations, the uncertainty of each result is kept on two digits, eventually shifted and rounded when it is more than two digits long.
- When converting back to string, the digits that are printed are all digits except the two last digits,
because the last digits are subject to uncertainty.
Uncertainties are kept in the internal representation of the number ; it is likely to use
tostr only for outputting data (on the screen or in a file),
and never call fromstr with the result of tostr.
It is better to always keep operands in their internal representation.
When you have to load another package, say bignum, there may be a conflict between the public procedures.
It may be slower than calling commands directly, but it might help you to use this library :
|
proc bigfloat {subcmd args} {
uplevel 1 [concat ::math::bigfloat::$subcmd $args]
}
set a [bigfloat sub [bigfloat fromstr 2.000] [bigfloat fromstr 0.530]]
puts [bigfloat tostr $a]
|
It might be useful for debugging and tracing, too.
floating-point, math, multiprecision, tcl
Copyright © 2004 Stephane Arnold <stephanearnold at yahoo dot fr>