1math::bigfloat(n) Tcl Math Library math::bigfloat(n)
2
3
4
5______________________________________________________________________________
6
8 math::bigfloat - Arbitrary precision floating-point numbers
9
11 package require Tcl 8.5
12
13 package require math::bigfloat ?2.0.1?
14
15 fromstr number ?trailingZeros?
16
17 tostr ?-nosci? number
18
19 fromdouble double ?decimals?
20
21 todouble number
22
23 isInt number
24
25 isFloat number
26
27 int2float integer ?decimals?
28
29 add x y
30
31 sub x y
32
33 mul x y
34
35 div x y
36
37 mod x y
38
39 abs x
40
41 opp x
42
43 pow x n
44
45 iszero x
46
47 equal x y
48
49 compare x y
50
51 sqrt x
52
53 log x
54
55 exp x
56
57 cos x
58
59 sin x
60
61 tan x
62
63 cotan x
64
65 acos x
66
67 asin x
68
69 atan x
70
71 cosh x
72
73 sinh x
74
75 tanh x
76
77 pi n
78
79 rad2deg radians
80
81 deg2rad degrees
82
83 round x
84
85 ceil x
86
87 floor x
88
89_________________________________________________________________
90
92 The bigfloat package provides arbitrary precision floating-point math
93 capabilities to the Tcl language. It is designed to work with Tcl 8.5,
94 but for Tcl 8.4 is provided an earlier version of this package. See
95 WHAT ABOUT TCL 8.4 ? for more explanations. By convention, we will
96 talk about the numbers treated in this library as :
97
98 · BigFloat for floating-point numbers of arbitrary length.
99
100 · integers for arbitrary length signed integers, just as basic
101 integers since Tcl 8.5.
102
103 Each BigFloat is an interval, namely [m-d, m+d], where m is the man‐
104 tissa and d the uncertainty, representing the limitation of that num‐
105 ber's precision. This is why we call such mathematics interval compu‐
106 tations. Just take an example in physics : when you measure a tempera‐
107 ture, not all digits you read are significant. Sometimes you just can‐
108 not trust all digits - not to mention if doubles (f.p. numbers) can
109 handle all these digits. BigFloat can handle this problem - trusting
110 the digits you get - plus the ability to store numbers with an arbi‐
111 trary precision. BigFloats are internally represented at Tcl lists:
112 this package provides a set of procedures operating against the inter‐
113 nal representation in order to :
114
115 · perform math operations on BigFloats and (optionnaly) with inte‐
116 gers.
117
118 · convert BigFloats from their internal representations to
119 strings, and vice versa.
120
122 fromstr number ?trailingZeros?
123 Converts number into a BigFloat. Its precision is at least the
124 number of digits provided by number. If the number contains
125 only digits and eventually a minus sign, it is considered as an
126 integer. Subsequently, no conversion is done at all.
127
128 trailingZeros - the number of zeros to append at the end of the
129 floating-point number to get more precision. It cannot be
130 applied to an integer.
131
132 # x and y are BigFloats : the first string contained a dot, and the second an e sign
133 set x [fromstr -1.000000]
134 set y [fromstr 2000e30]
135 # let's see how we get integers
136 set t 20000000000000
137 # the old way (package 1.2) is still supported for backwards compatibility :
138 set m [fromstr 10000000000]
139 # but we do not need fromstr for integers anymore
140 set n -39
141 # t, m and n are integers
142
143
144 The number's last digit is considered by the procedure to be
145 true at +/-1, For example, 1.00 is the interval [0.99, 1.01],
146 and 0.43 the interval [0.42, 0.44]. The Pi constant may be
147 approximated by the number "3.1415". This string could be con‐
148 sidered as the interval [3.1414 , 3.1416] by fromstr. So, when
149 you mean 1.0 as a double, you may have to write 1.000000 to get
150 enough precision. To learn more about this subject, see PRECI‐
151 SION.
152
153 For example :
154
155 set x [fromstr 1.0000000000]
156 # the next line does the same, but smarter
157 set y [fromstr 1. 10]
158
159
160 tostr ?-nosci? number
161 Returns a string form of a BigFloat, in which all digits are
162 exacts. All exact digits means a rounding may occur, for exam‐
163 ple to zero, if the uncertainty interval does not clearly show
164 the true digits. number may be an integer, causing the command
165 to return exactly the input argument. With the -nosci option,
166 the number returned is never shown in scientific notation, i.e.
167 not like '3.4523e+5' but like '345230.'.
168
169 puts [tostr [fromstr 0.99999]] ;# 1.0000
170 puts [tostr [fromstr 1.00001]] ;# 1.0000
171 puts [tostr [fromstr 0.002]] ;# 0.e-2
172
173 See PRECISION for that matter. See also iszero for how to
174 detect zeros, which is useful when performing a division.
175
176 fromdouble double ?decimals?
177 Converts a double (a simple floating-point value) to a BigFloat,
178 with exactly decimals digits. Without the decimals argument, it
179 behaves like fromstr. Here, the only important feature you
180 might care of is the ability to create BigFloats with a fixed
181 number of decimals.
182
183 tostr [fromstr 1.111 4]
184 # returns : 1.111000 (3 zeros)
185 tostr [fromdouble 1.111 4]
186 # returns : 1.111
187
188
189 todouble number
190 Returns a double, that may be used in expr, from a BigFloat.
191
192 isInt number
193 Returns 1 if number is an integer, 0 otherwise.
194
195 isFloat number
196 Returns 1 if number is a BigFloat, 0 otherwise.
197
198 int2float integer ?decimals?
199 Converts an integer to a BigFloat with decimals trailing zeros.
200 The default, and minimal, number of decimals is 1. When con‐
201 verting back to string, one decimal is lost:
202
203 set n 10
204 set x [int2float $n]; # like fromstr 10.0
205 puts [tostr $x]; # prints "10."
206 set x [int2float $n 3]; # like fromstr 10.000
207 puts [tostr $x]; # prints "10.00"
208
209
211 add x y
212
213 sub x y
214
215 mul x y
216 Return the sum, difference and product of x by y. x - may be
217 either a BigFloat or an integer y - may be either a BigFloat or
218 an integer When both are integers, these commands behave like
219 expr.
220
221 div x y
222
223 mod x y
224 Return the quotient and the rest of x divided by y. Each argu‐
225 ment (x and y) can be either a BigFloat or an integer, but you
226 cannot divide an integer by a BigFloat Divide by zero throws an
227 error.
228
229 abs x Returns the absolute value of x
230
231 opp x Returns the opposite of x
232
233 pow x n
234 Returns x taken to the nth power. It only works if n is an
235 integer. x might be a BigFloat or an integer.
236
238 iszero x
239 Returns 1 if x is :
240
241 · a BigFloat close enough to zero to raise "divide by
242 zero".
243
244 · the integer 0.
245 See here how numbers that are close to zero are converted to strings:
246
247 tostr [fromstr 0.001] ; # -> 0.e-2
248 tostr [fromstr 0.000000] ; # -> 0.e-5
249 tostr [fromstr -0.000001] ; # -> 0.e-5
250 tostr [fromstr 0.0] ; # -> 0.
251 tostr [fromstr 0.002] ; # -> 0.e-2
252
253 set a [fromstr 0.002] ; # uncertainty interval : 0.001, 0.003
254 tostr $a ; # 0.e-2
255 iszero $a ; # false
256
257 set a [fromstr 0.001] ; # uncertainty interval : 0.000, 0.002
258 tostr $a ; # 0.e-2
259 iszero $a ; # true
260
261
262 equal x y
263 Returns 1 if x and y are equal, 0 elsewhere.
264
265 compare x y
266 Returns 0 if both BigFloat arguments are equal, 1 if x is
267 greater than y, and -1 if x is lower than y. You would not be
268 able to compare an integer to a BigFloat : the operands should
269 be both BigFloats, or both integers.
270
272 sqrt x
273
274 log x
275
276 exp x
277
278 cos x
279
280 sin x
281
282 tan x
283
284 cotan x
285
286 acos x
287
288 asin x
289
290 atan x
291
292 cosh x
293
294 sinh x
295
296 tanh x The above functions return, respectively, the following : square
297 root, logarithm, exponential, cosine, sine, tangent, cotangent,
298 arc cosine, arc sine, arc tangent, hyperbolic cosine, hyperbolic
299 sine, hyperbolic tangent, of a BigFloat named x.
300
301 pi n Returns a BigFloat representing the Pi constant with n digits
302 after the dot. n is a positive integer.
303
304 rad2deg radians
305
306 deg2rad degrees
307 radians - angle expressed in radians (BigFloat)
308
309 degrees - angle expressed in degrees (BigFloat)
310
311 Convert an angle from radians to degrees, and vice versa.
312
314 round x
315
316 ceil x
317
318 floor x
319 The above functions return the x BigFloat, rounded like with the
320 same mathematical function in expr, and returns it as an inte‐
321 ger.
322
324 How do conversions work with precision ?
325
326 · When a BigFloat is converted from string, the internal represen‐
327 tation holds its uncertainty as 1 at the level of the last
328 digit.
329
330 · During computations, the uncertainty of each result is inter‐
331 nally computed the closest to the reality, thus saving the mem‐
332 ory used.
333
334 · When converting back to string, the digits that are printed are
335 not subject to uncertainty. However, some rounding is done, as
336 not doing so causes severe problems.
337
338 Uncertainties are kept in the internal representation of the number ;
339 it is recommended to use tostr only for outputting data (on the screen
340 or in a file), and NEVER call fromstr with the result of tostr. It is
341 better to always keep operands in their internal representation. Due
342 to the internals of this library, the uncertainty interval may be
343 slightly wider than expected, but this should not cause false digits.
344
345 Now you may ask this question : What precision am I going to get after
346 calling add, sub, mul or div? First you set a number from the string
347 representation and, by the way, its uncertainty is set:
348
349 set a [fromstr 1.230]
350 # $a belongs to [1.229, 1.231]
351 set a [fromstr 1.000]
352 # $a belongs to [0.999, 1.001]
353 # $a has a relative uncertainty of 0.1% : 0.001(the uncertainty)/1.000(the medium value)
354
355 The uncertainty of the sum, or the difference, of two numbers, is the
356 sum of their respective uncertainties.
357
358 set a [fromstr 1.230]
359 set b [fromstr 2.340]
360 set sum [add $a $b]]
361 # the result is : [3.568, 3.572] (the last digit is known with an uncertainty of 2)
362 tostr $sum ; # 3.57
363
364 But when, for example, we add or substract an integer to a BigFloat,
365 the relative uncertainty of the result is unchanged. So it is desirable
366 not to convert integers to BigFloats:
367
368 set a [fromstr 0.999999999]
369 # now something dangerous
370 set b [fromstr 2.000]
371 # the result has only 3 digits
372 tostr [add $a $b]
373
374 # how to keep precision at its maximum
375 puts [tostr [add $a 2]]
376
377
378 For multiplication and division, the relative uncertainties of the
379 product or the quotient, is the sum of the relative uncertainties of
380 the operands. Take care of division by zero : check each divider with
381 iszero.
382
383 set num [fromstr 4.00]
384 set denom [fromstr 0.01]
385
386 puts [iszero $denom];# true
387 set quotient [div $num $denom];# error : divide by zero
388
389 # opposites of our operands
390 puts [compare $num [opp $num]]; # 1
391 puts [compare $denom [opp $denom]]; # 0 !!!
392 # No suprise ! 0 and its opposite are the same...
393
394 Effects of the precision of a number considered equal to zero to the
395 cos function:
396
397 puts [tostr [cos [fromstr 0. 10]]]; # -> 1.000000000
398 puts [tostr [cos [fromstr 0. 5]]]; # -> 1.0000
399 puts [tostr [cos [fromstr 0e-10]]]; # -> 1.000000000
400 puts [tostr [cos [fromstr 1e-10]]]; # -> 1.000000000
401
402 BigFloats with different internal representations may be converted to
403 the same string.
404
405 For most analysis functions (cosine, square root, logarithm, etc.),
406 determining the precision of the result is difficult. It seems however
407 that in many cases, the loss of precision in the result is of one or
408 two digits. There are some exceptions : for example,
409
410 tostr [exp [fromstr 100.0 10]]
411 # returns : 2.688117142e+43 which has only 10 digits of precision, although the entry
412 # has 14 digits of precision.
413
414
416 If your setup do not provide Tcl 8.5 but supports 8.4, the package can
417 still be loaded, switching back to math::bigfloat 1.2. Indeed, an
418 important function introduced in Tcl 8.5 is required - the ability to
419 handle bignums, that we can do with expr. Before 8.5, this ability was
420 provided by several packages, including the pure-Tcl math::bignum pack‐
421 age provided by tcllib. In this case, all you need to know, is that
422 arguments to the commands explained here, are expected to be in their
423 internal representation. So even with integers, you will need to call
424 fromstr and tostr in order to convert them between string and internal
425 representations.
426
427 #
428 # with Tcl 8.5
429 # ============
430 set a [pi 20]
431 # round returns an integer and 'everything is a string' applies to integers
432 # whatever big they are
433 puts [round [mul $a 10000000000]]
434 #
435 # the same with Tcl 8.4
436 # =====================
437 set a [pi 20]
438 # bignums (arbitrary length integers) need a conversion hook
439 set b [fromstr 10000000000]
440 # round returns a bignum:
441 # before printing it, we need to convert it with 'tostr'
442 puts [tostr [round [mul $a $b]]]
443
444
446 We have not yet discussed about namespaces because we assumed that you
447 had imported public commands into the global namespace, like this:
448
449 namespace import ::math::bigfloat::*
450
451 If you matter much about avoiding names conflicts, I considere it
452 should be resolved by the following :
453
454 package require math::bigfloat
455 # beware: namespace ensembles are not available in Tcl 8.4
456 namespace eval ::math::bigfloat {namespace ensemble create -command ::bigfloat}
457 # from now, the bigfloat command takes as subcommands all original math::bigfloat::* commands
458 set a [bigfloat sub [bigfloat fromstr 2.000] [bigfloat fromstr 0.530]]
459 puts [bigfloat tostr $a]
460
461
463 Guess what happens when you are doing some astronomy. Here is an exam‐
464 ple :
465
466 # convert acurrate angles with a millisecond-rated accuracy
467 proc degree-angle {degrees minutes seconds milliseconds} {
468 set result 0
469 set div 1
470 foreach factor {1 1000 60 60} var [list $milliseconds $seconds $minutes $degrees] {
471 # we convert each entry var into milliseconds
472 set div [expr {$div*$factor}]
473 incr result [expr {$var*$div}]
474 }
475 return [div [int2float $result] $div]
476 }
477 # load the package
478 package require math::bigfloat
479 namespace import ::math::bigfloat::*
480 # work with angles : a standard formula for navigation (taking bearings)
481 set angle1 [deg2rad [degree-angle 20 30 40 0]]
482 set angle2 [deg2rad [degree-angle 21 0 50 500]]
483 set opposite3 [deg2rad [degree-angle 51 0 50 500]]
484 set sinProduct [mul [sin $angle1] [sin $angle2]]
485 set cosProduct [mul [cos $angle1] [cos $angle2]]
486 set angle3 [asin [add [mul $sinProduct [cos $opposite3]] $cosProduct]]
487 puts "angle3 : [tostr [rad2deg $angle3]]"
488
489
491 This document, and the package it describes, will undoubtedly contain
492 bugs and other problems. Please report such in the category math ::
493 bignum :: float of the Tcllib SF Trackers [http://source‐
494 forge.net/tracker/?group_id=12883]. Please also report any ideas for
495 enhancements you may have for either package and/or documentation.
496
498 computations, floating-point, interval, math, multiprecision, tcl
499
501 Copyright (c) 2004-2008, by Stephane Arnold <stephanearnold at yahoo dot fr>
502
503
504
505
506math 2.0.1 math::bigfloat(n)