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