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).
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.
#!/usr/local/bin/ruby
#
# pi.rb
# USAGE: ruby pi.rb n
# where n is the number of digits required.
# EX.: ruby pi.rb 1000
#
require "bigdecimal"
#
# Calculates 3.1415.... using J. Machin's formula.
#
def big_pi(sig) # sig: Number of significant figures
exp = -sig
pi = BigDecimal::new("0")
two = BigDecimal::new("2")
m25 = BigDecimal::new("-0.04")
m57121 = BigDecimal::new("-57121")
u = BigDecimal::new("1")
k = BigDecimal::new("1")
w = BigDecimal::new("1")
t = BigDecimal::new("-80")
while (u.exponent >= exp)
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 )
t,r = t.div(m57121,sig)
u,r = t.div(k,sig)
pi = pi + u
k = k+two
end
pi
end
if $0 == __FILE__
print "PI("+ARGV[0]+"):\n"
p pi(ARGV[0].to_i)
end