math::bigfloat(n) 1.2 math "Tcl Math Library"

NAME

math::bigfloat - Arbitrary precision floating-point numbers

TABLE OF CONTENTS

    TABLE OF CONTENTS
    SYNOPSIS
    DESCRIPTION
    INTRODUCTION
    ARITHMETICS
    COMPARISONS
    ANALYSIS
    ROUNDING
    PRECISION
    NAMESPACES AND OTHER PACKAGES
    EXAMPLES
    KEYWORDS
    COPYRIGHT

SYNOPSIS

package require Tcl ?8.4?
package require math::bignum ?3.0?
package require math::bigfloat ?1.2?

fromstr string ?trailingZeros?
fromstr -base radix string
tostr number
fromdouble double ?decimals?
todouble number
isInt number
isFloat number
int2float integer ?decimals?
add x y
sub x y
mul x y
div x y
mod x y
abs x
opp x
pow x n
iszero x
equal x y
compare x y
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
pi n
rad2deg radians
deg2rad degrees
round x
ceil x
floor x

DESCRIPTION

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 :

BigFloats are internally represented at Tcl lists: this package provides a set of procedures operating against the internal representation in order to :

INTRODUCTION

fromstr string ?trailingZeros?
Converts string into a BigFloat, or a BigInt. Its precision is at least the number of digits provided by string. If the string contains only digits and eventually a minus sign, it is considered as an integer.

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 throws an error.

fromstr -base radix string
Converts string representing an integer in the base radix, to a BigInt.

 
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
set octalNumber [fromstr -base 8 377]
# the result is 377 in octal, so it is equal to 255



The string's last digit is considered by the procedure to be true at +/-1. For instance, the Pi constant is irrational, so as you feed in the string "3.1415" it may be considered as a number in the interval [3.1414 , 3.1416]. This is why we call such mathematics interval computations. For example, 0.1 belongs to the interval [0.0, 0.2], and 1.00 to the interval [0.99,1.01].So, when you mean 1.0, you may have to write 1.000000 to get enough precision. If you encounter problems with precision, I recommend you read 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 raises an error : a single argument is required
# for strings to BigInts conversions
set n [fromstr 1 10]
# the next line is correct
set n [fromstr 1[string repeat 0 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. There is an issue with number equal to zero (see section PRECISION) : even if the precision about 0 is more than one digit, it will always be displayed as the '0' string.

fromdouble double ?decimals?
Converts a double (a simple floating-point value) to a BigFloat, with exactly decimals digits. Without the decimals argument, it behaves like fromstr.

 
tostr [fromstr 1.111 4]
# returns : 1.111000 (3 zeroes)
tostr [fromdouble 1.111 4]
# returns : 1.111



todouble number
Returns a double, that may be used in expr, from a BigFloat.

isInt number
Returns 1 if number is a BigInt, 0 otherwise.

isFloat number
Returns 1 if number is a BigFloat, 0 otherwise.

int2float integer ?decimals?
Converts a BigInt to a BigFloat with decimals trailing zeroes. When converting back to string, one decimal is lost. That is why the default, and minimal, number of decimals is 1.

ARITHMETICS

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 (x and y) 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.

COMPARISONS

iszero x
Returns 1 if x is :

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.

ANALYSIS

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, cosine, sine, tangent, cotangent, arc cosine, arc sine, arc tangent, hyperbolic cosine, hyperbolic sine, hyperbolic tangent, of a BigFloat named 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.

ROUNDING

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.

PRECISION

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

 
set a [fromstr 1.230]
# $a is internally 1.230 +/- d.10^-3
# 'd' is a number in the [1,2[ range
set a [fromstr 1.000]
# 'a' has a relative uncertainty in the range : ]0.1%,0.2%]
# because 1*10^-3/1.000=0.1%, and 2*10^-3/1.000=0.2%

The uncertainty of the sum, or the difference, of two numbers, is the sum of the uncertainty of each number.

 
set a [fromstr 1.230]
set b [fromstr 2.340]
puts [tostr [add $a $b]]
# the result is : 3.57 and the last digit of the sum is known with an uncertainty in the
# range [2*10^-3,4*10^-3[

But when operating a BigInt to a BigFloat (add, substract,etc.), the relative uncertainty of the result is unchanged. So it is likely to keep integers as BigInt and not to convert them to BigFloats.

For multiplication and division, the relative uncertainties of the product or the quotient, is the sum of the relative uncertainties of the operands.

Take care about the fact that if a number contains 0 in its uncertainty interval, it is always considered as if it was 0.

 
set num [fromstr 4.00]
set denom [fromstr 0.1];# $denom is 0, because [0.0,0.2] contains 0
puts [tostr $denom];# prints "0" on the screen
set quotient [div $num $denom];# throws an error : divide by zero
set oppn [opp $num]
set oppd [opp $denom]
puts [compare $num $oppn];#prints 1
puts [compare $denom $oppd];#prints 0 !

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 ?

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.

NAMESPACES AND OTHER PACKAGES

You might import public commands with the following :

 
namespace import ::math::bigfloat::*

If you matter much about avoiding names conflicts, I considere it should be resolved by the following :

 
# the math::bignum package is required by the following statement
package require math::bigfloat
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]

EXAMPLES

Guess what happens when you are doing some astronomy. Here is an example :

 
# convert acurrate angles with a millisecond-rated accuracy
proc degree-angle {degrees minutes seconds milliseconds} {
    set result [fromstr 0]
    set div [fromstr 1]
    foreach factor {1 1000 60 60} var [list $milliseconds $seconds $minutes $degrees] {
        # we convert each entry var into milliseconds
        set factor [fromstr $factor]
        set div [mul $div $factor]
        set result [add $result [mul [fromstr $var] $div]]
    }
    return [div [int2float $result] $div]
}
# load the package
package require math::bigfloat
namespace import ::math::bigfloat::*
# work with angles : a standard formula for navigation (taking bearings)
set angle1 [deg2rad [degree-angle 20 30 40   0]]
set angle2 [deg2rad [degree-angle 21  0 50 500]]
set opposite3 [deg2rad [degree-angle 51  0 50 500]]
set sinProduct [mul [sin $angle1] [sin $angle2]]
set cosProduct [mul [cos $angle1] [cos $angle2]]
set angle3 [asin [add [mul $sinProduct [cos $opposite3]] $cosProduct]]
puts "angle3 : [tostr [rad2deg $angle3]]"

KEYWORDS

floating-point, math, multiprecision, tcl

COPYRIGHT

Copyright © 2004-2005 Stephane Arnold <stephanearnold at yahoo dot fr>