ruby extconf.rb
make
make install
ruby extconf.rb
nmake
nmake install
require 'bigdecimal'
a=BigDecimal::new("0.123456789123456789")
b=BigDecimal::new("123456.78912345678",40)
c=a+b
p BigDecimal::double_fig # ==> 20 (depends on the CPU etc.)
The equivalent C programs which calculates the value of
double_fig is:
double v = 1.0;
int double_fig = 0;
while(v + 1.0 > 1.0) {
++double_fig;
v /= 10;
}
require "bigdecimal"
a = BigDecimal.new("0.12345")
p a.prec # ==> [8, 12]
b = BigDecimal.new("0.1234500000000")
p b.prec # ==> [8, 20]
c = BigDecimal.new("0.12345",20)
p c.prec # ==> [8, 24]
r and m are always the multiple of log10(BigDecimal::BASE).
- +
addition(c = a + b)
For the resulting number of significant digits of c,see Resulting number of significant digits.
- -
subtraction (c = a - b) or negation (c = -a)
For the resulting number of significant digits of c,see Resulting number of significant digits.
- *
multiplication(c = a * b)
For the resulting number of significant digits of c,see Resulting number of significant digits.
- /
division(c = a / b)
For the resulting number of significant digits of c,see Resulting number of significant digits.
- assign
c = a.assign(n,f)
assigns the value of a to c.
n is the number of significant digits of resulting c.
If f > 0,then a is assigned to c.
If f < 0,then -a is assigned to c.
The absolute value of f (|f|) must be 1 or 2.
If |f|=2,then proper round operation over c is performed,when the maximum
number of significant digits of c is less than current
number of significant digits of a.
If |f|=1 then extra digits are discarded when the maximum
number of significant digits of c is less than current
number of significant digits of a.
- add
c = a.add(b,n)
c = a.add(b,n) performs c = a + b.
If n is less than the actual significant digits of a + b,
then c is rounded properly.
- sub
c = a.sub(b,n)
c = a.sub(b,n) performs c = a - b.
If n is less than the actual significant digits of a - b,
then c is rounded properly.
- mult
c = a.mult(b,n)
c = a.mult(b,n) performs c = a * b.
If n is less than the actual significant digits of a * b,
then c is rounded properly.
- div
c,r = a.div(b,n)
c,r = a.div(b,n) performs c = a / b, r is the residue of a / b.
If necessary,the divide operation continues to n digits which c
can hold.
Unlike the divmod method,c is not always an integer.
c is never rounded,and the equation a = c*b + r is always
valid unless c is NaN or Infinity.
- %
r = a%b
is the same as:
r = a-((a/b).floor)*b
- fix
c = a.fix
returns integer part of a.
- frac
c = a.frac
returns fraction part of a.
- floor[(n)]
c = a.floor
returns the maximum integer value (in BigDecimal) which is less than or equal to a.
As shown in the following example,an optional integer argument (n) specifying the position
of 'floor'ed digit can be given.
If n> 0,then the (n+1)th digit counted from the decimal point in fraction part is 'floor'ed.
If n<0,then the n-th digit counted from the decimal point in integer part is 'floor'ed.
c = BigDecimal::new("1.23456")
d = c.floor(4) # d = 1.2345
c = BigDecimal::new("15.23456")
d = c.floor(-1) # d = 10.0
- ceil[(n)]
c = a.ceil
returns the minimum integer value (in BigDecimal) which is greater than or equal to a.
As shown in the following example,an optional integer argument (n) specifying the position
of 'ceil'ed digit can be given.
If n>0,then the (n+1)th digit counted from the decimal point in fraction part is 'ceil'ed.
If n<0,then the n-th digit counted from the decimal point in integer part is 'ceil'ed.
c = BigDecimal::new("1.23456")
d = c.ceil(4) # d = 1.2346
c = BigDecimal::new("15.23456")
d = c.ceil(-1) # d = 20.0
- round[(n)]
c = a.round
round off a to the nearest 1D
As shown in the following example,an optional integer argument (n) specifying the position
of rounded digit can be given.
If n>0,then the (n+1)th digit counted from the decimal point in fraction part is rounded.
If n<0,then the n-th digit counted from the decimal point in integer part is rounded.
c = BigDecimal::new("1.23456")
d = c.round(4) # d = 1.235
c = BigDecimal::new("15.23456")
d = c.round(-1) # d = 20.0
- truncate[(n)]
c = a.truncate
truncate a to the nearest 1D
As shown in the following example,an optional integer argument (n) specifying the position
of truncated digit can be given.
If n>0,then the (n+1)th digit counted from the decimal point in fraction part is truncated.
If n<0,then the n-th digit counted from the decimal point in integer part is truncated.
c = BigDecimal::new("1.23456")
d = c.truncate(4) # d = 1.2345
c = BigDecimal::new("15.23456")
d = c.truncate(-1) # d = 10.0
- divmod
c,r = a.divmod(b) # a = c*b + r
returns the quotient and remainder of a/b.
a = c * b + r is always satisfied.
where c is the integer sutisfying
c = (a/b).floor
and,therefore
r = a - c*b
- remainder
r=a.remainder(b)
returns the remainder of a/b.
where c is the integer sutisfying
c = (a/b).fix
and,therefore:
r = a - c*b
- abs
c = a.abs
returns an absolute value of a.
- to_i
changes a to an integer.
i = a.to_i
i becomes to Fixnum or Bignum.
IF a is Infinity or NaN,then i becomes to nil.
- to_s[(n)]
converts to string(results look like "0.xxxxxEn").
s = a.to_s
If n is given,then a space is inserted after every n digits for readability.
s = a.to_s(n)
- exponent
returns an integer holding exponent value of a.
n = a.exponent
means a = 0.xxxxxxx*10**n.
- to_f
same as dup method.
creates a new BigDecimal object having same value.
- E
e = BigDecimal::E(n)
where e(=2.718281828....) is the base value of natural logarithm.
n specifies the length of significant digits of e.
- PI
e = BigDecimal::PI(n)
returns at least n digits of the ratio of the circumference of a circle to its dirmeter
(pi=3.14159265358979....) using J.Machin's formula.
- BASE
Base value used in the BigDecimal calculation.
On 32 bit integer system,the value of BASE is 10000.
b = BigDecimal::BASE
- mode
mode method controls BigDecimal computation.
Following usage are defined.
f = BigDecimal::mode(BigDecimal::EXCEPTION_NaN,flag)
f = BigDecimal::mode(BigDecimal::EXCEPTION_INFINITY,flag)
f = BigDecimal::mode(BigDecimal::EXCEPTION_UNDERFLOW,flag)
f = BigDecimal::mode(BigDecimal::EXCEPTION_OVERFLOW,flag)
f = BigDecimal::mode(BigDecimal::EXCEPTION_ZERODIVIDE,flag)
f = BigDecimal::mode(BigDecimal::EXCEPTION_ALL,flag)
EXCEPTION_NaN controls the execution once computation results to NaN.
EXCEPTION_INFINITY controls the execution once computation results to Infinity(}Infinity).
EXCEPTION_UNDERFLOW controls the execution once computation underflows.
EXCEPTION_OVERFLOW controls the execution once computation overflows.
EXCEPTION_ZERODIVIDE controls the execution once zero-division occures.
EXCEPTION_ALL controls the execution for any exception defined occures.
If the flag is true,then the relating exception is thrown.
No exception is thrown when the flag is false(default) and computation
continues with the result:
EXCEPTION_NaN results to NaN
EXCEPTION_INFINITY results to +Infinity or -Infinity
EXCEPTION_UNDERFLOW results to 0.
EXCEPTION_OVERFLOW results to +Infinity or -Infinity
EXCEPTION_ZERODIVIDE results to +Infinity or -Infinity
EXCEPTION_INFINITY,EXCEPTION_OVERFLOW, and EXCEPTION_ZERODIVIDE are
currently the same.
The return value of mode method is the value set.
Suppose the return value of the mode method is f,then
f & BigDecimal::EXCEPTION_NaN !=0 means EXCEPTION_NaN is set to on.
If the value of the argument flag is other than nil,true nor false then
current mode status is returned.
- limit[(n)]
Limits the maximum digits that the newly created BigDecimal objects can hold
never exceed n. Returns maximum value before set.
Zero,the default value,means no upper limit.
mf = BigDecimal::limit(n)
- sign
returns the 'attribute'.
n = a.sign
where the value of n means that a is:
n = BigDecimal::SIGN_NaN(0) : a is NaN
n = BigDecimal::SIGN_POSITIVE_ZERO(1) : a is +0
n = BigDecimal::SIGN_NEGATIVE_ZERO(-1) : a is -0
n = BigDecimal::SIGN_POSITIVE_FINITE(2) : a is positive
n = BigDecimal::SIGN_NEGATIVE_FINITE(-2) : a is negative
n = BigDecimal::SIGN_POSITIVE_INFINITE(3) : a is +Infinity
n = BigDecimal::SIGN_NEGATIVE_INFINITE(-3) : a is -Infinity
The value in () is the actual value,see (Internal structure.
- nan?
a.nan? returns True when a is NaN.
- infinite?
a.infinite? returns True when a is + or -.
- finite?
a.finite? returns True when a is neither nor NaN.
- to_parts
decomposes a BigDecimal value to 4 parts.
All 4 parts are returned as an array.
Parts consist of a sign(0 when the value is NaN,+1 for positive and
-1 for negative value), a string representing fraction part,base value(always 10 currently),and an integer(Fixnum) for exponent respectively.
a=BigDecimal::new("3.14159265",10)
f,x,y,z = a.to_parts
where f=+1,x="314159265",y=10 and z=1
therefore,you can translate BigDecimal value to Float as:
s = "0."+x
b = f*(s.to_f)*(y**z)
- inspect
is used for debugging output.
p a=BigDecimal::new("3.14",10)
should produce output like "#<0x112344:'0.314E1',4(12)%gt;".
where "0x112344" is the address,
'0.314E1' is the value,4 is the number of the significant digits,
and 12 is the maximum number of the significant digits
the object can hold.
- dup
creates a new BigDecimal object having same value.
- sqrt
c = a.sqrt(n)
computes square root value of a with significant digit number n at least.
- sincos
computes and returns sine and cosine value of a with significant digit number n at least.
sin,cos = a.sincos(n)
- exp
c = a.exp(n)
computes the base of natural logarithm value(e=2.718281828....) powered by a
with significant digit number n at least.
- power
c = a.power(n)
returns the value of a powered by n(c=a**n).
n must be an integer.
- zero?
c = a.zero?
returns true if a is equal to 0,otherwise returns false
- nonzero?
c = a.nonzero?
returns false if a is 0,otherwise returns a itself.
- <=>
c = a <=> b
returns 0 if a==b,1 if a > b,and returns -1 if a < b.
a = BigDecimal.E(20)
c = a * "0.123456789123456789123456789" # A String is changed to BigDecimal object.
is performed normally.
a = BigDecimal.E(20)
c = "0.123456789123456789123456789" * a # ERROR
If you actually have any inconvenience about the error above.
You can define a new class derived from String class,
and define coerce method within the new class.
require "BigDecimal"
aa = %w(1 -1 +0.0 -0.0 +Infinity -Infinity NaN)
ba = %w(1 -1 +0.0 -0.0 +Infinity -Infinity NaN)
opa = %w(+ - * / <=> > >= < == != <=)
for a in aa
for b in ba
for op in opa
x = BigDecimal::new(a)
y = BigDecimal::new(b)
eval("ans= x #{op} y;print a,' ',op,' ',b,' ==> ',ans.to_s,\"\n\"")
end
end
end
typedef struct {
VALUE obj; /* Back pointer(VALUE) for Ruby object. */
unsigned long MaxPrec; /* The size of the array frac[] */
unsigned long Prec; /* Current size of frac[] actually used. */
short sign; /* Attribute of the value. */
/* ==0 : NaN */
/* 1 : +0 */
/* -1 : -0 */
/* 2 : Positive number */
/* -2 : Negative number */
/* 3 : +Infinity */
/* -3 : -Infinity */
unsigned short flag; /* Control flag */
int exponent; /* Exponent value(0.xxxx*BASE**exponent) */
unsigned long frac[1]; /* An araay holding mantissa(Variable) */
} Real;
The decimal value 1234.56784321 is represented as(BASE=10000):0.1234 5678 4321*(10000)**1where frac[0]=1234,frac[1]=5678,frac[2]=4321, Prec=3,sign=2,exponent=1. MaxPrec can be any value greater than or equal to Prec.
file = File::open(....,"r")
s = BigDecimal::new("0")
while line = file.gets
s = s + line
end
If the internal representation is binary,translation from decimal to
binary is required and the translation error is inevitable.
For example, 0.1 can not exactly be represented in binary.
e = BigDecimal.new("1")
while e + 1.0 != 1.0
e = e / 10
end
Above example continues till all available memories is exhausted.
(Because no round operation is performed on e+1.0)
#
# PI (Calculates 3.1415.... using J. Machin's formula.
#
sig = 2000 # <== Number of significant figures
exp = -sig
sig = sig + sig/100 # no theoretical reason
pi = BigDecimal::new("0")
two = BigDecimal::new("2")
m25 = BigDecimal::new("-0.04")
m57121 = BigDecimal::new("-57121")
n1 = 0
n2 = 0
u = BigDecimal::new("1")
k = BigDecimal::new("1")
w = BigDecimal::new("1")
t = BigDecimal::new("-80")
while (u.exponent >= exp)
n1 += 1
t = t*m25
u,r = t.div(k,sig)
pi = pi + u
k = k+two
end
u = BigDecimal::new("1")
k = BigDecimal::new("1")
w = BigDecimal::new("1")
t = BigDecimal::new("956")
while (u.exponent >= exp )
n2 += 1
t,r = t.div(m57121,sig)
u,r = t.div(k,sig)
pi = pi + u
k = k+two
end
p pi
print "# of iterations = ",n1,"+",n2,"\n"
exit