Change soft-fail to use the config, rather than env
[rbx.git] / stdlib / ext / bigdecimal / bigdecimal_en.html
blobc2b86faef6c877b46f6f9516df7157b33109a80f
1 <!-- saved from url=(0022)http://internet.e-mail -->
2 <HTML>
3 <HEAD>
4 <META HTTP-EQUIV="Content-Type" CONTENT="text/html">
5 <style type="text/css"><!--
6 body { color: #3f0f0f; background: #fefeff; margin-left: 2em; margin-right: 2em;}
7 h1 { color: #ffffff; background-color: #3939AD; border-color: #FF00FF; width: 100%; border-style: solid;
8 border-top-width: 0.1em; border-bottom-width: 0.1em; border-right: none; border-left: none;
9 padding: 0.1em; font-weight: bold; font-size: 160%; text-align: center;}
10 h2 { color: #00007f; background-color: #e7e7ff; border-color: #000094; width: 100%; border-style: solid; border-le ft: none; border-right: none; border-top-width: 0.1em; border-bottom-width: 0.1em; padding: 0.1em;
11 font-weight: bold; font-size: 110%;
13 h3 { color: #00007f; padding: 0.2em; font-size: 110%;}
14 h4, h5 { color: #000000; padding: 0.2em; font-size: 100%;}
15 table { margin-top: 0.2em; margin-bottom: 0.2em; margin-left: 2em; margin-right: 2em;}
16 caption { color: #7f0000; font-weight: bold;}
17 th { background: #e7e7ff; padding-left: 0.2em; padding-right: 0.2em;}
18 td { background: #f3f7ff; padding-left: 0.2em; padding-right: 0.2em;}
19 code { color: #0000df;}
20 dt { margin-top: 0.2em;}
21 li { margin-top: 0.2em;}
22 pre
23 { BACKGROUND-COLOR: #d0d0d0; BORDER-BOTTOM: medium none; BORDER-LEFT: medium none;
24 BORDER-RIGHT: medium none; BORDER-TOP: medium none; LINE-HEIGHT: 100%; MARGIN: 12px 12px 12px 12px;
25 PADDING-BOTTOM: 12px; PADDING-LEFT: 12px; PADDING-RIGHT: 12px; PADDING-TOP: 12px;
26 WHITE-SPACE: pre; WIDTH: 100%
28 --></style>
30 <TITLE>BigDecimal:An extension library for Ruby</TITLE>
31 </HEAD>
32 <BODY BGCOLOR=#FFFFE0>
33 <H1>BigDecimal(Variable Precision Floating Library for Ruby)</H1>
34 <DIV align="right"><A HREF="./bigdecimal_ja.html">Japanese</A></DIV><BR>
35 BigDecimal is an extension library for the Ruby interpreter.
36 Using BigDecimal class, you can obtain any number of significant digits in computation.
37 For the details about Ruby see:<BR>
38 <UL>
39 <LI><A HREF="http://www.ruby-lang.org/en/">http://www.ruby-lang.org/en/</A>:Official Ruby page(English).</LI>
40 <LI><A HREF="http://kahori.com/ruby/ring/">http://kahori.com/ruby/ring/</A>:Mutually linked pages relating to Ruby(Japanese).
41 </LI>
42 </UL>
43 NOTE:<BR>
44 This software is provided "AS IS" and without any express or
45 implied warranties,including,without limitation,the implied
46 warranties of merchantibility and fitness for a particular
47 purpose. For the details,see COPYING and README included in this
48 distribution.
49 <BR>
50 <hr>
52 <H2>Contents</H2>
53 <UL>
54 <LI><A HREF="#INTRO">Introduction</LI>
55 <LI><A HREF="#SPEC">Usage and methods</A></LI>
56 <LI><A HREF="#UNDEF">Infinity,NaN,Zero</A></LI>
57 <LI><A HREF="#STRUCT">Internal structure</A></LI>
58 <LI><A HREF="#BASE">Binary or decimal number representation</A></LI>
59 <LI><A HREF="#PREC">Resulting number of significant digits</A></LI>
60 </UL>
61 <HR>
63 <A NAME="#INTRO">
64 <H2>Introduction</H2>
65 Ruby already has builtin (variable length integer number) class Bignum. Using Bignum class,you can obtain
66 any integer value in magnitude. But, variable length decimal number class is not yet built in.
67 This is why I made variable length floating class BigDecimal.
68 Feel free to send any comments or bug reports to me.
69 <A HREF="mailto:shigeo@tinyforest.gr.jp">shigeo@tinyforest.gr.jp</A>
70 I will try(but can't promise) to fix bugs reported.
71 <hr>
72 <H2>Installation</H2>
73 The Ruby latest version can be downloaded from <A HREF="http://www.ruby-lang.org/en/">Official Ruby page</A>.
74 Once decompress the downloaded Ruby archive,follow the normal installation procedures according to the
75 documents included.
77 <A NAME="#SPEC">
78 <H2>Usage and methods</H2>
79 Suppose you already know Ruby programming,
80 to create BigDecimal objects,the program would like:<BR>
82 <CODE><PRE>
83 require 'bigdecimal'
84 a=BigDecimal::new("0.123456789123456789")
85 b=BigDecimal("123456.78912345678",40)
86 c=a+b
87 </PRE></CODE>
89 <H3>List of methods</H3>
90 In 32 bits integer system,every 4 digits(in decimal) are computed simultaneously.
91 This means the number of significant digits in BigDecimal is always a multiple of 4.
92 <P>
93 Some more methods are available in Ruby code (not C code).
94 Functions such as sin,cos ...,are in math.rb in bigdecimal directory.
95 To use them,require math.rb as:
96 <CODE><PRE>
97 require "bigdecimal/math.rb"
98 </PRE></CODE>
99 For details,see the math.rb code and comments.
100 Other utility methods are in util.rb.
101 To use util.rb, require it as:
102 <CODE><PRE>
103 require "bigdecimal/util.rb"
104 </PRE></CODE>
105 For details,see the util.rb code.
107 <H4><U>Class methods</U></H4>
108 <UL>
109 <LI><B>new</B></LI><BLOCKQUOTE>
110 "new" method creates a new BigDecimal object.<BR>
111 a=BigDecimal::new(s[,n]) or<BR>
112 a=BigDecimal(s[,n]) or<BR>
113 where:<BR>
114 s: Initial value string. Spaces will be ignored. Any unrecognizable character for
115 representing initial value terminates the string.<BR>
116 n: Maximum number of significant digits of a. n must be a Fixnum object.
117 If n is omitted or is equal to 0,then the maximum number of significant digits of a is determined from the length of s.
118 Actual number of digits handled in computations are usually gretaer than n.<BR>
119 n is useful when performing divisions like
120 <CODE><PRE>
121 BigDecimal("1") / BigDecimal("3") # => 0.3333333333 33E0
122 BigDecimal("1",10) / BigDecimal("3",10) # => 0.3333333333 3333333333 33333333E0
123 </PRE></CODE>
124 but the resulting digits obtained may differ in future version.
125 </BLOCKQUOTE>
127 <LI><B>mode</B></LI><BLOCKQUOTE>
128 f = BigDecimal.mode(s[,v])<BR>
129 mode method controls BigDecimal computation. If the second argument is not given or is nil,then the value
130 of current setting is returned.
131 Following usage are defined.<BR>
132 <P><B>[EXCEPTION control]</B><P>
133 Actions when computation results NaN or Infinity can be defined as follows.
135 <BLOCKQUOTE>
136 f = BigDecimal::mode(BigDecimal::EXCEPTION_NaN,flag)<BR>
137 f = BigDecimal::mode(BigDecimal::EXCEPTION_INFINITY,flag)<BR>
138 f = BigDecimal::mode(BigDecimal::EXCEPTION_UNDERFLOW,flag)<BR>
139 f = BigDecimal::mode(BigDecimal::EXCEPTION_OVERFLOW,flag)<BR>
140 f = BigDecimal::mode(BigDecimal::EXCEPTION_ZERODIVIDE,flag)<BR>
141 f = BigDecimal::mode(BigDecimal::EXCEPTION_ALL,flag)<BR>
142 </BLOCKQUOTE>
143 EXCEPTION_NaN controls the execution when computation results to NaN.<BR>
144 EXCEPTION_INFINITY controls the execution when computation results to Infinity(�}Infinity).<BR>
145 EXCEPTION_UNDERFLOW controls the execution when computation underflows.<BR>
146 EXCEPTION_OVERFLOW controls the execution when computation overflows.<BR>
147 EXCEPTION_ZERODIVIDE controls the execution when zero-division occures.<BR>
148 EXCEPTION_ALL controls the execution for any exception defined occures.<BR>
149 If the flag is true,then the relating exception is thrown.<BR>
150 No exception is thrown when the flag is false(default) and computation
151 continues with the result:<BR>
152 <BLOCKQUOTE>
153 EXCEPTION_NaN results to NaN<BR>
154 EXCEPTION_INFINITY results to +Infinity or -Infinity<BR>
155 EXCEPTION_UNDERFLOW results to 0.<BR>
156 EXCEPTION_OVERFLOW results to +Infinity or -Infinity<BR>
157 EXCEPTION_ZERODIVIDE results to +Infinity or -Infinity<BR>
158 </BLOCKQUOTE>
159 EXCEPTION_INFINITY,EXCEPTION_OVERFLOW, and EXCEPTION_ZERODIVIDE are
160 currently the same.<BR>
161 The return value of mode method is the value set.<BR>
162 If nil is specified for the second argument,then current setting is returned.<BR>
163 Suppose the return value of the mode method is f,then
164 f &amp; BigDecimal::EXCEPTION_NaN !=0 means EXCEPTION_NaN is set to on.
166 <B>[ROUND error control]</B><P>
167 Rounding operation can be controlled as:
168 <BLOCKQUOTE>
169 f = BigDecimal::mode(BigDecimal::ROUND_MODE,flag)
170 </BLOCKQUOTE>
171 where flag must be one of:
172 <TABLE>
174 <TR><TD>ROUND_UP</TD><TD>round away from zero.</TD></TR>
175 <TR><TD>ROUND_DOWN</TD><TD>round towards zero(truncate).</TD></TR>
176 <TR><TD>ROUND_HALF_UP</TD><TD>round up if the digit &gt;= 5 otherwise truncated(default).</TD></TR>
177 <TR><TD>ROUND_HALF_DOWN</TD><TD>round up if the digit &gt;= 6 otherwise truncated.</TD></TR>
178 <TR><TD>ROUND_HALF_EVEN</TD><TD>round towards the even neighbor(Banker's rounding).
179 <TR><TD>ROUND_CEILING</TD><TD>round towards positive infinity(ceil).</TD></TR>
180 <TR><TD>ROUND_FLOOR</TD><TD>round towards negative infinity(floor).</TD></TR>
181 </TABLE>
182 New rounding mode is returned. If nil is specified for the second argument,then current setting is returned.<BR>
183 The digit location for rounding operation can not be specified by this mode method,
184 use truncate/round/ceil/floor/add/sub/mult/div mthods for each instance instead.
185 </BLOCKQUOTE>
187 <LI><B>limit[(n)]</B></LI><BLOCKQUOTE>
188 Limits the maximum digits that the newly created BigDecimal objects can hold never exceed n.
189 This means the rounding operation specified by BigDecimal.mode is
190 performed if necessary.
191 limit returns the value before set if n is nil or is not specified.
192 Zero,the default value,means no upper limit.<BR>
193 The limit has no more priority than instance methods such as truncate,round,ceil,floor,add,sub,mult,and div. <BR>
194 mf = BigDecimal::limit(n)<BR>
195 </BLOCKQUOTE>
197 <LI><B>double_fig</B></LI><BLOCKQUOTE>
198 double_fig is a class method which returns the number of digits
199 the Float class can have.
200 <CODE><PRE>
201 p BigDecimal::double_fig # ==> 20 (depends on the CPU etc.)
202 </PRE></CODE>
203 The equivalent C programs which calculates the value of
204 double_fig is:
205 <CODE><PRE>
206 double v = 1.0;
207 int double_fig = 0;
208 while(v + 1.0 > 1.0) {
209 ++double_fig;
210 v /= 10;
212 </PRE></CODE>
213 </BLOCKQUOTE>
215 <LI><B>BASE</B></LI><BLOCKQUOTE>
216 Base value used in the BigDecimal calculation.
217 On 32 bits integer system,the value of BASE is 10000.<BR>
218 b = BigDecimal::BASE<BR>
219 </BLOCKQUOTE>
220 </UL>
222 <H4><U>Instance methods</U></H4>
223 <UL>
224 <LI><B>+</B></LI><BLOCKQUOTE>
225 addition(c = a + b)<BR>
226 For the resulting number of significant digits of c,see <A HREF="#PREC">Resulting number of significant digits</A>.
228 </BLOCKQUOTE>
229 <LI><B>-</B></LI><BLOCKQUOTE>
230 subtraction (c = a - b) or negation (c = -a)<BR>
231 For the resulting number of significant digits of c,see <A HREF="#PREC">Resulting number of significant digits</A>.
233 </BLOCKQUOTE>
234 <LI><B>*</B></LI><BLOCKQUOTE>
235 multiplication(c = a * b)<BR>
236 For the resulting number of significant digits of c,see <A HREF="#PREC">Resulting number of significant digits</A>.
238 </BLOCKQUOTE>
239 <LI><B>/</B></LI><BLOCKQUOTE>
240 division(c = a / b)<BR>
241 For the resulting number of significant digits of c,see <A HREF="#PREC">Resulting number of significant digits</A>.
242 </BLOCKQUOTE>
244 <LI><B>add(b,n)</B></LI><BLOCKQUOTE>
245 c = a.add(b,n)<BR>
246 c = a.add(b,n) performs c = a + b.<BR>
247 If n is less than the actual significant digits of a + b,
248 then c is rounded properly according to the BigDecimal.limit.<BR>
249 If n is zero,then the result is the same as +'s.
250 </BLOCKQUOTE>
251 <LI><B>sub(b,n)</B></LI><BLOCKQUOTE>
252 c = a.sub(b,n)<BR>
253 c = a.sub(b,n) performs c = a - b.<BR>
254 If n is less than the actual significant digits of a - b,
255 then c is rounded properly according to the BigDecimal.limit.<BR>
256 If n is zero,then the result is the same as -'s.
258 </BLOCKQUOTE>
259 <LI><B>mult(b,n)</B></LI><BLOCKQUOTE>
260 c = a.mult(b,n)<BR>
261 c = a.mult(b,n) performs c = a * b.<BR>
262 If n is less than the actual significant digits of a * b,
263 then c is rounded properly according to the BigDecimal.limit.<BR>
264 If n is zero,then the result is the same as *'s.
266 </BLOCKQUOTE>
267 <LI><B>div(b[,n])</B></LI><BLOCKQUOTE>
268 c = a.div(b,n)<BR>
269 c = a.div(b,n) performs c = a / b.<BR>
270 If n is less than the actual significant digits of a / b,
271 then c is rounded properly according to the BigDecimal.limit.<BR>
272 If n is zero,then the result is the same as /'s.
273 If n is not given,then the result will be an integer(BigDecimal) like Float#div.
274 </BLOCKQUOTE>
276 <LI><B>fix</B></LI><BLOCKQUOTE>
277 c = a.fix<BR>
278 returns integer part of a.<BR>
280 </BLOCKQUOTE>
281 <LI><B>frac</B></LI><BLOCKQUOTE>
282 c = a.frac<BR>
283 returns fraction part of a.<BR>
285 </BLOCKQUOTE>
286 <LI><B>floor[(n)]</B></LI><BLOCKQUOTE>
287 c = a.floor<BR>
288 returns the maximum integer value (in BigDecimal) which is less than or equal to a.
289 <CODE><PRE>
290 c = BigDecimal("1.23456").floor # ==> 1
291 c = BigDecimal("-1.23456").floor # ==> -2
292 </PRE></CODE>
294 As shown in the following example,an optional integer argument (n) specifying the position
295 of the target digit can be given.<BR>
296 If n> 0,then the (n+1)th digit counted from the decimal point in fraction part is processed(resulting number of fraction part digits is less than or equal to n).<BR>
297 If n<0,then the n-th digit counted from the decimal point in integer part is processed(at least n 0's are placed from the decimal point to left).
298 <CODE><PRE>
299 c = BigDecimal("1.23456").floor(4) # ==> 1.2345
300 c = BigDecimal("15.23456").floor(-1) # ==> 10.0
301 </PRE></CODE>
303 </BLOCKQUOTE>
304 <LI><B>ceil[(n)]</B></LI><BLOCKQUOTE>
305 c = a.ceil<BR>
306 returns the minimum integer value (in BigDecimal) which is greater than or equal to a.
307 <CODE><PRE>
308 c = BigDecimal("1.23456").ceil # ==> 2
309 c = BigDecimal("-1.23456").ceil # ==> -1
310 </PRE></CODE>
312 As shown in the following example,an optional integer argument (n) specifying the position
313 of the target digit can be given.<BR>
314 If n>0,then the (n+1)th digit counted from the decimal point in fraction part is processed(resulting number of fraction part digits is less than or equal to n).<BR>
315 If n<0,then the n-th digit counted from the decimal point in integer part is processed(at least n 0's are placed from the decimal point to left).
316 <CODE><PRE>
317 c = BigDecimal("1.23456").ceil(4) # ==> 1.2346
318 c = BigDecimal("15.23456").ceil(-1) # ==> 20.0
319 </PRE></CODE>
321 </BLOCKQUOTE>
322 <LI><B>round[(n[,b])]</B></LI><BLOCKQUOTE>
323 c = a.round<BR>
324 round a to the nearest 1(default)�D<BR>
325 <CODE><PRE>
326 c = BigDecimal("1.23456").round # ==> 1
327 c = BigDecimal("-1.23456").round # ==> -1
328 </PRE></CODE>
329 The rounding operation changes according to BigDecimal::mode(BigDecimal::ROUND_MODE,flag) if specified.
331 As shown in the following example,an optional integer argument (n) specifying the position
332 of the target digit can be given.<BR>
333 If n>0,then the (n+1)th digit counted from the decimal point in fraction part is processed(resulting number of fraction part digits is less than or equal to n).<BR>
334 If n<0,then the n-th digit counted from the decimal point in integer part is processed(at least n 0's are placed from the decimal point to left).
335 <CODE><PRE>
336 c = BigDecimal::new("1.23456").round(4) # ==> 1.2346
337 c = BigDecimal::new("15.23456").round(-1) # ==> 20.0
338 </PRE></CODE>
340 Rounding operation can be specified by setting the second optional argument b with the valid ROUND_MODE.<BR>
341 <CODE><PRE>
342 c = BigDecimal::new("1.23456").round(3,BigDecimal::ROUND_HALF_EVEN) # ==> 1.234
343 c = BigDecimal::new("1.23356").round(3,BigDecimal::ROUND_HALF_EVEN) # ==> 1.234
344 </PRE></CODE>
346 </BLOCKQUOTE>
347 <LI><B>truncate[(n)]</B></LI><BLOCKQUOTE>
348 c = a.truncate<BR>
349 truncate a to the nearest 1�D<BR>
350 As shown in the following example,an optional integer argument (n) specifying the position
351 of the target digit can be given.<BR>
352 If n>0,then the (n+1)th digit counted from the decimal point in fraction part is processed(resulting number of fraction part digits is less than or equal to n).<BR>
353 If n<0,then the n-th digit counted from the decimal point in integer part is processed(at least n 0's are placed from the decimal point to left).
355 <CODE><PRE>
356 c = BigDecimal::new("1.23456").truncate(4) # ==> 1.2345
357 c = BigDecimal::new("15.23456").truncate(-1) # ==> 10.0
358 </PRE></CODE>
359 </BLOCKQUOTE>
360 <LI><B>abs</B></LI><BLOCKQUOTE>
361 c = a.abs<BR>
362 returns an absolute value of a.<BR>
364 </BLOCKQUOTE>
365 <LI><B>to_i</B></LI><BLOCKQUOTE>
366 changes a to an integer.<BR>
367 i = a.to_i<BR>
368 i becomes to Fixnum or Bignum.
369 If a is Infinity or NaN,then i becomes to nil.
371 </BLOCKQUOTE>
372 <LI><B>to_s[(n)]</B></LI><BLOCKQUOTE>
373 converts to string(default results look like "0.xxxxxEn").
374 <CODE><PRE>
375 BigDecimal("1.23456").to_s # ==> "0.123456E1"
376 </PRE></CODE>
377 If n(>0) is given,then a space is inserted to each of two parts divided by the decimal point
378 after every n digits for readability.
379 <CODE><PRE>
380 BigDecimal("0.1234567890123456789").to_s(10) # ==> "0.1234567890 123456789E0"
381 </PRE></CODE>
382 n can be a string representing a positive integer number.
383 <CODE><PRE>
384 BigDecimal("0.1234567890123456789").to_s("10") # ==> "0.1234567890 123456789E0"
385 </PRE></CODE>
386 If the first character is '+'(or ' '),then '+'(or ' ') will be set before value string
387 when the value is positive.
388 <CODE><PRE>
389 BigDecimal("0.1234567890123456789").to_s(" 10") # ==> " 0.1234567890 123456789E0"
390 BigDecimal("0.1234567890123456789").to_s("+10") # ==> "+0.1234567890 123456789E0"
391 BigDecimal("-0.1234567890123456789").to_s("10") # ==> "-0.1234567890 123456789E0"
392 </PRE></CODE>
394 At the end of the string,'E'(or 'e') or 'F'(or 'f') can be specified to change
395 number representation.
396 <CODE><PRE>
397 BigDecimal("1234567890.123456789").to_s("E") # ==> "0.1234567890123456789E10"
398 BigDecimal("1234567890.123456789").to_s("F") # ==> "1234567890.123456789"
399 BigDecimal("1234567890.123456789").to_s("5E") # ==> "0.12345 67890 12345 6789E10"
400 BigDecimal("1234567890.123456789").to_s("5F") # ==> "12345 67890.12345 6789"
401 </PRE></CODE>
403 </BLOCKQUOTE>
404 <LI><B>exponent</B></LI><BLOCKQUOTE>
405 returns an integer holding exponent value of a.<BR>
406 n = a.exponent <BR>
407 means a = 0.xxxxxxx*10**n.
408 </BLOCKQUOTE>
410 <LI><B>precs</B></LI><BLOCKQUOTE>
411 n,m = a.precs <BR>
412 prec returns number of significant digits (n) and maximum number of
413 significant digits (m) of a.
414 </BLOCKQUOTE>
416 <LI><B>to_f</B></LI><BLOCKQUOTE>
417 Creates a new Float object having (nearly) the same value.
418 Use split method if you want to convert by yourself.
419 </BLOCKQUOTE>
421 </BLOCKQUOTE>
422 <LI><B>sign</B></LI><BLOCKQUOTE>
423 n = a.sign <BR>
424 returns positive value if a &gt; 0,negative value if a &lt; 0,
425 otherwise zero if a == 0.<BR>
426 where the value of n means that a is:<BR>
427 n = BigDecimal::SIGN_NaN(0) : a is NaN<BR>
428 n = BigDecimal::SIGN_POSITIVE_ZERO(1) : a is +0<BR>
429 n = BigDecimal::SIGN_NEGATIVE_ZERO(-1) : a is -0<BR>
430 n = BigDecimal::SIGN_POSITIVE_FINITE(2) : a is positive<BR>
431 n = BigDecimal::SIGN_NEGATIVE_FINITE(-2) : a is negative<BR>
432 n = BigDecimal::SIGN_POSITIVE_INFINITE(3) : a is +Infinity<BR>
433 n = BigDecimal::SIGN_NEGATIVE_INFINITE(-3) : a is -Infinity<BR>
434 The value in () is the actual value,see (<A HREF="#STRUCT">Internal structure</A>.<BR>
436 </BLOCKQUOTE>
437 <LI><B>nan?</B></LI><BLOCKQUOTE>
438 a.nan? returns True when a is NaN.
440 </BLOCKQUOTE>
441 <LI><B>infinite?</B></LI><BLOCKQUOTE>
442 a.infinite? returns 1 when a is +�‡,-1 when a is -�‡, nil otherwise.
444 </BLOCKQUOTE>
445 <LI><B>finite?</B></LI><BLOCKQUOTE>
446 a.finite? returns true when a is neither �‡ nor NaN.
447 </BLOCKQUOTE>
449 <LI><B>zero?</B></LI><BLOCKQUOTE>
450 c = a.zero?<BR>
451 returns true if a is equal to 0,otherwise returns false<BR>
452 </BLOCKQUOTE>
453 <LI><B>nonzero?</B></LI><BLOCKQUOTE>
454 c = a.nonzero?<BR>
455 returns nil if a is 0,otherwise returns a itself.<BR>
456 </BLOCKQUOTE>
458 <LI><B>split</B></LI><BLOCKQUOTE>
459 decomposes a BigDecimal value to 4 parts.
460 All 4 parts are returned as an array.<BR>
461 Parts consist of a sign(0 when the value is NaN,+1 for positive and
462 -1 for negative value), a string representing fraction part,base value(always 10 currently),and an integer(Fixnum) for exponent respectively.
463 a=BigDecimal::new("3.14159265")<BR>
464 f,x,y,z = a.split<BR>
465 where f=+1,x="314159265",y=10 and z=1<BR>
466 therefore,you can translate BigDecimal value to Float as:<BR>
467 s = "0."+x<BR>
468 b = f*(s.to_f)*(y**z)<BR>
470 </BLOCKQUOTE>
471 <LI><B>inspect</B></LI><BLOCKQUOTE>
472 is used for debugging output.<BR>
473 p a=BigDecimal::new("3.14",10)<BR>
474 should produce output like "#&lt;0x112344:'0.314E1',4(12)%gt;".
475 where "0x112344" is the address,
476 '0.314E1' is the value,4 is the number of the significant digits,
477 and 12 is the maximum number of the significant digits
478 the object can hold.
479 </BLOCKQUOTE>
481 <LI><B>sqrt</B></LI><BLOCKQUOTE>
482 c = a.sqrt(n)<BR>
483 computes square root value of a with significant digit number n at least.<BR>
484 </BLOCKQUOTE>
486 <LI><B>**</B></LI><BLOCKQUOTE>
487 c = a ** n<BR>
488 returns the value of a powered by n.
489 n must be an integer.<BR>
491 </BLOCKQUOTE>
492 <LI><B>power</B></LI><BLOCKQUOTE>
493 The same as ** method.<BR>
494 c = a.power(n)<BR>
495 returns the value of a powered by n(c=a**n).
496 n must be an integer.<BR>
497 </BLOCKQUOTE>
499 <LI><B>divmod,quo,modulo,%,remainder</B></LI><BLOCKQUOTE>
500 See,corresponding methods in Float class.
501 </BLOCKQUOTE>
503 </BLOCKQUOTE>
504 <LI><B>&lt;=&gt;</B></LI><BLOCKQUOTE>
505 c = a &lt;=&gt; b <BR>
506 returns 0 if a==b,1 if a &gt b,and returns -1 if a &lt b.<BR>
507 </BLOCKQUOTE>
508 </UL>
510 Following methods need no explanation.<BR>
511 <UL>
512 <LI>==</LI>
513 <LI>===</LI>
514 same as ==,used in case statement.
515 <LI>!=</LI>
516 <LI>&lt;</LI>
517 <LI>&lt;=</LI>
518 <LI>&gt;</LI>
519 <LI>&gt;=</LI>
520 </UL>
522 <HR>
523 <H3>About 'coerce'</H3>
524 <B>For the binary operation like A op B:</B>
525 <DL>
526 <DT> 1.Both A and B are BigDecimal objects</DT>
527 <DD> A op B is normally performed.</DD>
528 <DT> 2.A is the BigDecimal object but B is other than BigDecimal object</DT>
529 <DD> Operation is performed,after B is translated to correcponding BigDecimal object(because BigDecimal supports coerce method).</DD>
530 <DT> 3.A is not the BigDecimal object but B is BigDecimal object</DT>
531 <DD>If A has coerce mthod,then B will translate A to corresponding
532 BigDecimal object and the operation is performed,otherwise an error occures.</DD>
533 </DL>
535 String is not translated to BigDecimal in default.
536 Uncomment /* #define ENABLE_NUMERIC_STRING */ in bigdecimal.c, compile and install
537 again if you want to enable string to BigDecimal conversion.
538 Translation stops without error at the character representing non digit.
539 For instance,"10XX" is translated to 10,"XXXX" is translated to 0.<BR>
540 String representing zero or infinity such as "Infinity","+Infinity","-Infinity",and "NaN" can also be translated to BigDecimal unless false is specified by mode method.<BR>
542 BigDecimal class supports coerce method(for the details about coerce method,see Ruby documentations). This means the most binary operation can be performed if the BigDecimal object is at the left hand side of the operation.<BR><BR>
544 For example:
545 <CODE><PRE>
546 a = BigDecimal.E(20)
547 c = a * "0.123456789123456789123456789" # A String is changed to BigDecimal object.
548 </PRE></CODE>
549 is performed normally.<BR>
550 But,because String does not have coerce method,the following example can not be performed.<BR>
552 <CODE><PRE>
553 a = BigDecimal.E(20)
554 c = "0.123456789123456789123456789" * a # ERROR
555 </PRE></CODE>
557 If you actually have any inconvenience about the error above.
558 You can define a new class derived from String class,
559 and define coerce method within the new class.<BR>
561 <hr>
562 <A NAME="#UNDEF">
563 <H2>Infinity,Not a Number(NaN),Zero</H2>
564 Infinite numbers and NaN can be represented by string writing "+Infinity"(or "Infinity"),"-Infinity",and "NaN" respectively in your program.
565 Infinite numbers can be obtained by 1.0/0.0(=Infinity) or -1.0/0.0(=-Infinity).
566 <BR><BR>
567 NaN(Not a number) can be obtained by undefined computation like 0.0/0.0
568 or Infinity-Infinity.
569 Any computation including NaN results to NaN.
570 Comparisons with NaN never become true,including comparison with NaN itself.
571 <BR><BR>
572 Zero has two different variations as +0.0 and -0.0.
573 But,still, +0.0==-0.0 is true.
574 <BR><BR>
575 Computation results including Infinity,NaN,+0.0 or -0.0 become complicated.
576 Run following program and comfirm the results.
577 Send me any incorrect result if you find.
579 <CODE><PRE>
580 require "bigdecimal"
581 aa = %w(1 -1 +0.0 -0.0 +Infinity -Infinity NaN)
582 ba = %w(1 -1 +0.0 -0.0 +Infinity -Infinity NaN)
583 opa = %w(+ - * / <=> > >= < == != <=)
584 for a in aa
585 for b in ba
586 for op in opa
587 x = BigDecimal::new(a)
588 y = BigDecimal::new(b)
589 eval("ans= x #{op} y;print a,' ',op,' ',b,' ==> ',ans.to_s,\"\n\"")
593 </PRE></CODE>
594 <hr>
596 <A NAME="#STRUCT">
597 <H2>Internal structure</H2>
598 BigDecimal number is defined by the structure Real in BigDecimal.h.
599 Digits representing a float number are kept in the array frac[] defined in the structure.
600 In the program,any floating number(BigDecimal number) is represented as:<BR>
601 <BigDecimal number> = 0.xxxxxxxxx*BASE**n<BR><BR>
602 where 'x' is any digit representing mantissa(kept in the array frac[]),
603 BASE is base value(=10000 in 32 bit integer system),
604 and n is the exponent value.<BR>
605 Larger BASE value enables smaller size of the array frac[],and increases computation speed.
606 The value of BASE is defined ind VpInit(). In 32 bit integer system,this value is
607 10000. In 64 bit integer system,the value becomes larger.
608 BigDecimal has not yet been compiled and tested on 64 bit integer system.
609 It will be very nice if anyone try to run BigDecimal on 64 bit system and
610 inform me the results.
611 When BASE is 10000,an element of the array frac[] can have vale of from 0 to 9999.
612 (up to 4 digits).<BR>
613 The structure Real is defined in bigdecimal.h as:<BR>
614 <CODE><PRE>
615 typedef struct {
616 VALUE obj; /* Back pointer(VALUE) for Ruby object. */
617 unsigned long MaxPrec; /* The size of the array frac[] */
618 unsigned long Prec; /* Current size of frac[] actually used. */
619 short sign; /* Attribute of the value. */
620 /* ==0 : NaN */
621 /* 1 : +0 */
622 /* -1 : -0 */
623 /* 2 : Positive number */
624 /* -2 : Negative number */
625 /* 3 : +Infinity */
626 /* -3 : -Infinity */
627 unsigned short flag; /* Control flag */
628 int exponent; /* Exponent value(0.xxxx*BASE**exponent) */
629 unsigned long frac[1]; /* An araay holding mantissa(Variable) */
630 } Real;
631 </CODE></PRE>
632 The decimal value 1234.56784321 is represented as(BASE=10000):<BR>
633 <PRE>
634 0.1234 5678 4321*(10000)**1
635 </PRE>
636 where frac[0]=1234,frac[1]=5678,frac[2]=4321,
637 Prec=3,sign=2,exponent=1. MaxPrec can be any value greater than or equal to
638 Prec.
639 <hr>
641 <A NAME="#BASE">
642 <H2>Binary or decimal number representation</H2>
643 I adopted decimal number representation for BigDecimal implementation.
644 Of cource,binary number representation is common on the most computers.
646 <H3>Advantages using decimal representation</H3>
647 The reason why I adopted decimal number representation for BigDecimal is:<BR>
648 <DL>
649 <DT>Easy for debugging
650 <DD>The floating number 1234.56784321 can be easily represented as:<BR>
651 frac[0]=1234,frac[1]=5678,frac[2]=4321,exponent=1,and sign=2.
652 <DT>Exact representation
653 <DD>Following program can add all numbers(in decimal) in a file
654 without any error(no round operation).<BR>
656 <CODE><PRE>
657 file = File::open(....,"r")
658 s = BigDecimal::new("0")
659 while line = file.gets
660 s = s + line
662 </PRE></CODE>
664 If the internal representation is binary,translation from decimal to
665 binary is required and the translation error is inevitable.
666 For example, 0.1 can not exactly be represented in binary.<BR>
667 0.1 => b1*2**(-1)+b1*2**(-2)+b3*2**(-3)+b4*2**(-4)....<BR>
668 where b1=0,b2=0,b3=0,b4=1...<BR>
669 bn(n=1,2,3,...) is infinite series of digit with value of 0 or 1,
670 and rounding operation is necessary but where we should round the series ?
671 Of cource,exact "0.1" is printed if the rouding operation is properly done,
672 <DT>Significant digit we can have is automatically determined
673 <DD>In binary representation,0.1 can not be represented in finite series of digit.
675 But we only need one element(frac[0]=1) in decimal representation.
676 This means that we can always determine the size of the array frac[] in Real
677 structure.
678 </DL>
680 <H3>Disadvantage of decimal representation</H3>
681 Because most computers have no internal decimal representaion.
682 Once you use BigDecimal,you need to keep using it without
683 considering computation cost if exact computation is required.
685 <H4>Which is the first input?</H4>
686 Because most people uses decimal notatin for numeric data representation,
687 BigDecimal can handle numeric data without loss of translation error.
688 <hr>
690 <A NAME="#PREC">
691 <H2>Resulting number of significant digits</H2>
692 For the fundamental arithmetics such as addition,subtraction,
693 multiplication,and division,I prepared 2 group of methods<BR>
695 <H3>1. +,-,*,/</H3>
696 For the operation + - * /,you can not specify the resulting
697 number of significant digits.<BR>
698 Resulting number of significant digits are defined as:<BR>
699 1.1 For *,resulting number of significant digits is the sum of the
700 significant digits of both side of the operator. For / ,resulting number of significant digits is the sum of the
701 maximum significant digits of both side of the operator.<BR>
702 1.2 For + and -,resulting number of significant digits is determined so that
703 no round operation is needed. <br>
704 For example, c has more than 100 siginificant digits if c is computed as:<BR>
705 c = 0.1+0.1*10**(-100)<br>
706 <BR>
707 As +,-,and * are always exact(no round operation is performed unless BigDecimal.limit is specified),
708 which means more momories are required to keep computation results.
709 But,the division such as c=1.0/3.0 will always be rounded.<BR>
711 <H3>2. add,sub,mult,div</H3>
712 The length of the significant digits obtained from +,-,*,/
713 is always defined by that of right and left side of the operator.
714 To specify the length of the significant digits by your self,
715 use methos add,sub,mult,div.
716 <CODE><PRE>
717 BigDecimal("2").div(3,12) # 2.0/3.0 => 0.6666666666 67E0
718 </PRE></CODE>
719 </BLOCKQUOTE>
721 <H3>3. truncate,round,ceil,floor</H3>
722 Using these methods,you can specify rounding location relatively from
723 decimal point.
724 <CODE><PRE>
725 BigDecimal("6.66666666666666").round(12) # => 0.6666666666 667E1
726 </PRE></CODE>
727 </BLOCKQUOTE>
730 <H3>4. Example</H3>
731 Following example compute the ratio of the circumference of a circle to
732 its dirmeter(pi=3.14159265358979....) using J.Machin's formula.
733 <BR><BR>
734 <CODE><PRE>
735 #!/usr/local/bin/ruby
737 require "bigdecimal"
739 # Calculates 3.1415.... (the number of times that a circle's diameter
740 # will fit around the circle) using J. Machin's formula.
742 def big_pi(sig) # sig: Number of significant figures
743 exp = -sig
744 pi = BigDecimal::new("0")
745 two = BigDecimal::new("2")
746 m25 = BigDecimal::new("-0.04")
747 m57121 = BigDecimal::new("-57121")
749 u = BigDecimal::new("1")
750 k = BigDecimal::new("1")
751 w = BigDecimal::new("1")
752 t = BigDecimal::new("-80")
753 while (u.nonzero? && u.exponent >= exp)
754 t = t*m25
755 u = t.div(k,sig)
756 pi = pi + u
757 k = k+two
760 u = BigDecimal::new("1")
761 k = BigDecimal::new("1")
762 w = BigDecimal::new("1")
763 t = BigDecimal::new("956")
764 while (u.nonzero? && u.exponent >= exp )
765 t = t.div(m57121,sig)
766 u = t.div(k,sig)
767 pi = pi + u
768 k = k+two
773 if $0 == __FILE__
774 if ARGV.size == 1
775 print "PI("+ARGV[0]+"):\n"
776 p big_pi(ARGV[0].to_i)
777 else
778 print "TRY: ruby pi.rb 1000 \n"
782 </PRE></CODE>
783 <HR>
784 <FONT size=2>
786 <A HREF="http://www.tinyforest.gr.jp">
787 Shigeo Kobayashi
788 </A>
789 (E-Mail:<A HREF="mailto:shigeo@tinyforest.gr.jp">&lt;shigeo@tinyforest.gr.jp&gt;</U></A>)
790 </I>
791 </FONT>
792 </TD>
793 </TR>
794 </TABLE>
795 </BODY>
796 </HTML>