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