~ubuntu-branches/ubuntu/quantal/ruby1.9.1/quantal

« back to all changes in this revision

Viewing changes to ext/bigdecimal/lib/bigdecimal/math.rb

  • Committer: Bazaar Package Importer
  • Author(s): Lucas Nussbaum
  • Date: 2011-09-24 19:16:17 UTC
  • mfrom: (1.1.8 upstream) (13.1.7 experimental)
  • Revision ID: james.westby@ubuntu.com-20110924191617-o1qz4rcmqjot8zuy
Tags: 1.9.3~rc1-1
* New upstream release: 1.9.3 RC1.
  + Includes load.c fixes. Closes: #639959.
* Upload to unstable.

Show diffs side-by-side

added added

removed removed

Lines of Context:
7
7
#   sin (x, prec)
8
8
#   cos (x, prec)
9
9
#   atan(x, prec)  Note: |x|<1, x=0.9999 may not converge.
10
 
#   exp (x, prec)
11
10
#   log (x, prec)
12
11
#   PI  (prec)
13
12
#   E   (prec) == exp(1.0,prec)
146
145
    y
147
146
  end
148
147
 
149
 
  # Computes the value of e (the base of natural logarithms) raised to the
150
 
  # power of x, to the specified number of digits of precision.
151
 
  #
152
 
  # If x is infinite or NaN, returns NaN.
153
 
  #
154
 
  # BigMath::exp(BigDecimal.new('1'), 10).to_s
155
 
  # -> "0.271828182845904523536028752390026306410273E1"
156
 
  def exp(x, prec)
157
 
    raise ArgumentError, "Zero or negative precision for exp" if prec <= 0
158
 
    return BigDecimal("NaN") if x.infinite? || x.nan?
159
 
    n    = prec + BigDecimal.double_fig
160
 
    one  = BigDecimal("1")
161
 
    x = -x if neg = x < 0
162
 
    x1 = one
163
 
    y  = one
164
 
    d  = y
165
 
    z  = one
166
 
    i  = 0
167
 
    while d.nonzero? && ((m = n - (y.exponent - d.exponent).abs) > 0)
168
 
      m = BigDecimal.double_fig if m < BigDecimal.double_fig
169
 
      x1  = x1.mult(x,n)
170
 
      i += 1
171
 
      z *= i
172
 
      d  = x1.div(z,m)
173
 
      y += d
174
 
    end
175
 
    if neg
176
 
      one.div(y, prec)
177
 
    else
178
 
      y.round(prec - y.exponent)
179
 
    end
180
 
  end
181
 
 
182
 
  # Computes the natural logarithm of x to the specified number of digits
183
 
  # of precision.
184
 
  #
185
 
  # Returns x if x is infinite or NaN.
186
 
  #
187
 
  def log(x, prec)
188
 
    raise ArgumentError, "Zero or negative argument for log" if x <= 0 || prec <= 0
189
 
    return x if x.infinite? || x.nan?
190
 
    one = BigDecimal("1")
191
 
    two = BigDecimal("2")
192
 
    n  = prec + BigDecimal.double_fig
193
 
    if (expo = x.exponent) < 0 || expo >= 3
194
 
      x = x.mult(BigDecimal("1E#{-expo}"), n)
195
 
    else
196
 
      expo = nil
197
 
    end
198
 
    x  = (x - one).div(x + one,n)
199
 
    x2 = x.mult(x,n)
200
 
    y  = x
201
 
    d  = y
202
 
    i = one
203
 
    while d.nonzero? && ((m = n - (y.exponent - d.exponent).abs) > 0)
204
 
      m = BigDecimal.double_fig if m < BigDecimal.double_fig
205
 
      x  = x2.mult(x,n)
206
 
      i += two
207
 
      d  = x.div(i,m)
208
 
      y += d
209
 
    end
210
 
    y *= two
211
 
    if expo
212
 
      y += log(BigDecimal("10"),prec) * BigDecimal(expo.to_s)
213
 
    end
214
 
    y
215
 
  end
216
 
 
217
148
  # Computes the value of pi to the specified number of digits of precision.
218
149
  def PI(prec)
219
150
    raise ArgumentError, "Zero or negative argument for PI" if prec <= 0