flt 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/History.txt +41 -0
- data/License.txt +20 -0
- data/Manifest.txt +42 -0
- data/README.txt +557 -0
- data/Rakefile +34 -0
- data/lib/flt.rb +9 -0
- data/lib/flt/b.rb +6 -0
- data/lib/flt/bigdecimal.rb +151 -0
- data/lib/flt/bin_num.rb +250 -0
- data/lib/flt/d.rb +6 -0
- data/lib/flt/dec_num.rb +1239 -0
- data/lib/flt/float.rb +458 -0
- data/lib/flt/math.rb +66 -0
- data/lib/flt/num.rb +4211 -0
- data/lib/flt/sugar.rb +102 -0
- data/lib/flt/support.rb +1335 -0
- data/lib/flt/tolerance.rb +561 -0
- data/lib/flt/tolerance/sugar.rb +77 -0
- data/lib/flt/version.rb +9 -0
- data/setup.rb +1585 -0
- data/tasks/ann.rake +80 -0
- data/tasks/bones.rake +20 -0
- data/tasks/gem.rake +192 -0
- data/tasks/git.rake +40 -0
- data/tasks/manifest.rake +48 -0
- data/tasks/notes.rake +27 -0
- data/tasks/post_load.rake +39 -0
- data/tasks/rdoc.rake +50 -0
- data/tasks/rubyforge.rake +55 -0
- data/tasks/setup.rb +279 -0
- data/tasks/spec.rake +54 -0
- data/tasks/svn.rake +47 -0
- data/tasks/test.rake +40 -0
- data/test/all_tests.rb +23 -0
- data/test/helper.rb +101 -0
- data/test/reader.rb +68 -0
- data/test/test_basic.rb +396 -0
- data/test/test_bin.rb +245 -0
- data/test/test_bin_arithmetic.rb +94 -0
- data/test/test_binfloat_conversion.rb +24 -0
- data/test/test_coercion.rb +22 -0
- data/test/test_comparisons.rb +53 -0
- data/test/test_dectest.rb +216 -0
- data/test/test_define_conversions.rb +144 -0
- data/test/test_epsilon.rb +55 -0
- data/test/test_exact.rb +147 -0
- data/test/test_flags.rb +34 -0
- data/test/test_multithreading.rb +32 -0
- data/test/test_num_constructor.rb +133 -0
- data/test/test_odd_even.rb +78 -0
- data/test/test_round.rb +104 -0
- data/test/test_to_int.rb +104 -0
- data/test/test_to_rf.rb +36 -0
- data/test/test_tol.rb +102 -0
- data/test/test_ulp.rb +127 -0
- metadata +147 -0
data/lib/flt/d.rb
ADDED
data/lib/flt/dec_num.rb
ADDED
@@ -0,0 +1,1239 @@
|
|
1
|
+
require 'flt/num'
|
2
|
+
|
3
|
+
module Flt
|
4
|
+
|
5
|
+
# DecNum arbitrary precision floating point number.
|
6
|
+
# This implementation of DecNum is based on the Decimal module of Python,
|
7
|
+
# written by Eric Price, Facundo Batista, Raymond Hettinger, Aahz and Tim Peters.
|
8
|
+
class DecNum < Num
|
9
|
+
|
10
|
+
class << self
|
11
|
+
# Numerical base of DecNum.
|
12
|
+
def radix
|
13
|
+
10
|
14
|
+
end
|
15
|
+
|
16
|
+
# Integral power of the base: radix**n for integer n; returns an integer.
|
17
|
+
def int_radix_power(n)
|
18
|
+
10**n
|
19
|
+
end
|
20
|
+
|
21
|
+
# Multiply by an integral power of the base: x*(radix**n) for x,n integer;
|
22
|
+
# returns an integer.
|
23
|
+
def int_mult_radix_power(x,n)
|
24
|
+
x * (10**n)
|
25
|
+
end
|
26
|
+
|
27
|
+
# Divide by an integral power of the base: x/(radix**n) for x,n integer;
|
28
|
+
# returns an integer.
|
29
|
+
def int_div_radix_power(x,n)
|
30
|
+
x / (10**n)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# This is the Context class for Flt::DecNum.
|
35
|
+
#
|
36
|
+
# The context defines the arithmetic context: rounding mode, precision,...
|
37
|
+
#
|
38
|
+
# DecNum.context is the current (thread-local) context for DecNum numbers.
|
39
|
+
class Context < Num::ContextBase
|
40
|
+
# See Flt::Num::ContextBase#new() for the valid options
|
41
|
+
#
|
42
|
+
# See also the context constructor method Flt::Num.Context().
|
43
|
+
def initialize(*options)
|
44
|
+
super(DecNum, *options)
|
45
|
+
end
|
46
|
+
|
47
|
+
# Power. See DecNum#power()
|
48
|
+
def power(x,y,modulo=nil)
|
49
|
+
_convert(x).power(y,modulo,self)
|
50
|
+
end
|
51
|
+
|
52
|
+
# Returns the base 10 logarithm
|
53
|
+
def log10(x)
|
54
|
+
_convert(x).log10(self)
|
55
|
+
end
|
56
|
+
|
57
|
+
# Exponential function: e**x
|
58
|
+
def exp(x)
|
59
|
+
_convert(x).exp(self)
|
60
|
+
end
|
61
|
+
|
62
|
+
# Returns the natural (base e) logarithm
|
63
|
+
def ln(x)
|
64
|
+
_convert(x).ln(self)
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
|
69
|
+
# the DefaultContext is the base for new contexts; it can be changed.
|
70
|
+
DefaultContext = DecNum::Context.new(
|
71
|
+
:exact=>false, :precision=>28, :rounding=>:half_even,
|
72
|
+
:emin=> -999999999, :emax=>+999999999,
|
73
|
+
:flags=>[],
|
74
|
+
:traps=>[DivisionByZero, Overflow, InvalidOperation],
|
75
|
+
:ignored_flags=>[],
|
76
|
+
:capitals=>true,
|
77
|
+
:clamp=>true)
|
78
|
+
|
79
|
+
BasicContext = DecNum::Context.new(DefaultContext,
|
80
|
+
:precision=>9, :rounding=>:half_up,
|
81
|
+
:traps=>[DivisionByZero, Overflow, InvalidOperation, Clamped, Underflow],
|
82
|
+
:flags=>[])
|
83
|
+
|
84
|
+
ExtendedContext = DecNum::Context.new(DefaultContext,
|
85
|
+
:precision=>9, :rounding=>:half_even,
|
86
|
+
:traps=>[], :flags=>[], :clamp=>false)
|
87
|
+
|
88
|
+
# A DecNum value can be defined by:
|
89
|
+
# * A String containing a text representation of the number
|
90
|
+
# * An Integer
|
91
|
+
# * A Rational
|
92
|
+
# * A Value of a type for which conversion is defined in the context.
|
93
|
+
# * Another DecNum.
|
94
|
+
# * A sign, coefficient and exponent (either as separate arguments, as an array or as a Hash with symbolic keys),
|
95
|
+
# or a signed coefficient and an exponent.
|
96
|
+
# This is the internal representation of Num, as returned by Num#split.
|
97
|
+
# The sign is +1 for plus and -1 for minus; the coefficient and exponent are
|
98
|
+
# integers, except for special values which are defined by :inf, :nan or :snan for the exponent.
|
99
|
+
#
|
100
|
+
# An optional Context can be passed after the value-definint argument to override the current context
|
101
|
+
# and options can be passed in a last hash argument; alternatively context options can be overriden
|
102
|
+
# by options of the hash argument.
|
103
|
+
#
|
104
|
+
# When the number is defined by a numeric literal (a String), it can be followed by a symbol that specifies
|
105
|
+
# the mode used to convert the literal to a floating-point value:
|
106
|
+
# * :free is currently the default for all cases. The precision of the input literal (including trailing zeros)
|
107
|
+
# is preserved and the precision of the context is ignored.
|
108
|
+
# When the literal is in base 10, (which is the case by default), the literal is preserved exactly.
|
109
|
+
# Otherwise, all significative digits that can be derived from the literal are generanted, significative
|
110
|
+
# meaning here that if the digit is changed and the value converted back to a literal of the same base and
|
111
|
+
# precision, the original literal will not be obtained.
|
112
|
+
# * :short is a variation of :free in which only the minimun number of digits that are necessary to
|
113
|
+
# produce the original literal when the value is converted back with the same original precision.
|
114
|
+
# * :fixed will round and normalize the value to the precision specified by the context (normalize meaning
|
115
|
+
# that exaclty the number of digits specified by the precision will be generated, even if the original
|
116
|
+
# literal has fewer digits.) This may fail returning NaN (and raising Inexact) if the context precision is
|
117
|
+
# :exact, but not if the floating-point radix is a multiple of the input base.
|
118
|
+
#
|
119
|
+
# Options that can be passed for construction from literal:
|
120
|
+
# * :base is the numeric base of the input, 10 by default.
|
121
|
+
#
|
122
|
+
# The Flt.DecNum() constructor admits the same parameters and can be used as a shortcut for DecNum creation.
|
123
|
+
# Examples:
|
124
|
+
# DecNum('0.1000') # -> 0.1000
|
125
|
+
# DecNum('0.12345') # -> 0.12345
|
126
|
+
# DecNum('1.2345E-1') # -> 0.12345
|
127
|
+
# DecNum('0.1000', :short) # -> 0.1000
|
128
|
+
# DecNum('0.1000',:fixed, :precision=>20) # -> 0.10000000000000000000
|
129
|
+
# DecNum('0.12345',:fixed, :precision=>20) # -> 0.12345000000000000000
|
130
|
+
# DecNum('0.100110E3', :base=>2) # -> 4.8
|
131
|
+
# DecNum('0.1E-5', :free, :base=>2) # -> 0.016
|
132
|
+
# DecNum('0.1E-5', :short, :base=>2) # -> 0.02
|
133
|
+
# DecNum('0.1E-5', :fixed, :base=>2, :exact=>true) # -> 0.015625
|
134
|
+
# DecNum('0.1E-5', :fixed, :base=>2) # -> 0.01562500000000000000000000000
|
135
|
+
def initialize(*args)
|
136
|
+
super(*args)
|
137
|
+
end
|
138
|
+
|
139
|
+
def number_of_digits
|
140
|
+
@coeff.is_a?(Integer) ? _number_of_digits(@coeff) : 0
|
141
|
+
end
|
142
|
+
|
143
|
+
# Raises to the power of x, to modulo if given.
|
144
|
+
#
|
145
|
+
# With two arguments, compute self**other. If self is negative then other
|
146
|
+
# must be integral. The result will be inexact unless other is
|
147
|
+
# integral and the result is finite and can be expressed exactly
|
148
|
+
# in 'precision' digits.
|
149
|
+
#
|
150
|
+
# With three arguments, compute (self**other) % modulo. For the
|
151
|
+
# three argument form, the following restrictions on the
|
152
|
+
# arguments hold:
|
153
|
+
#
|
154
|
+
# - all three arguments must be integral
|
155
|
+
# - other must be nonnegative
|
156
|
+
# - at least one of self or other must be nonzero
|
157
|
+
# - modulo must be nonzero and have at most 'precision' digits
|
158
|
+
#
|
159
|
+
# The result of a.power(b, modulo) is identical to the result
|
160
|
+
# that would be obtained by computing (a**b) % modulo with
|
161
|
+
# unbounded precision, but is computed more efficiently. It is
|
162
|
+
# always exact.
|
163
|
+
def power(other, modulo=nil, context=nil)
|
164
|
+
|
165
|
+
if context.nil? && (modulo.is_a?(Context) || modulo.is_a?(Hash))
|
166
|
+
context = modulo
|
167
|
+
modulo = nil
|
168
|
+
end
|
169
|
+
|
170
|
+
return self.power_modulo(other, modulo, context) if modulo
|
171
|
+
|
172
|
+
context = DecNum.define_context(context)
|
173
|
+
other = _convert(other)
|
174
|
+
|
175
|
+
ans = _check_nans(context, other)
|
176
|
+
return ans if ans
|
177
|
+
|
178
|
+
# 0**0 = NaN (!), x**0 = 1 for nonzero x (including +/-Infinity)
|
179
|
+
if other.zero?
|
180
|
+
if self.zero?
|
181
|
+
return context.exception(InvalidOperation, '0 ** 0')
|
182
|
+
else
|
183
|
+
return Num(1)
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
# result has sign -1 iff self.sign is -1 and other is an odd integer
|
188
|
+
result_sign = +1
|
189
|
+
_self = self
|
190
|
+
if _self.sign == -1
|
191
|
+
if other.integral?
|
192
|
+
result_sign = -1 if !other.even?
|
193
|
+
else
|
194
|
+
# -ve**noninteger = NaN
|
195
|
+
# (-0)**noninteger = 0**noninteger
|
196
|
+
unless self.zero?
|
197
|
+
return context.exception(InvalidOperation, 'x ** y with x negative and y not an integer')
|
198
|
+
end
|
199
|
+
end
|
200
|
+
# negate self, without doing any unwanted rounding
|
201
|
+
_self = self.copy_negate
|
202
|
+
end
|
203
|
+
|
204
|
+
# 0**(+ve or Inf)= 0; 0**(-ve or -Inf) = Infinity
|
205
|
+
if _self.zero?
|
206
|
+
return (other.sign == +1) ? Num(result_sign, 0, 0) : num_class.infinity(result_sign)
|
207
|
+
end
|
208
|
+
|
209
|
+
# Inf**(+ve or Inf) = Inf; Inf**(-ve or -Inf) = 0
|
210
|
+
if _self.infinite?
|
211
|
+
return (other.sign == +1) ? num_class.infinity(result_sign) : Num(result_sign, 0, 0)
|
212
|
+
end
|
213
|
+
|
214
|
+
# 1**other = 1, but the choice of exponent and the flags
|
215
|
+
# depend on the exponent of self, and on whether other is a
|
216
|
+
# positive integer, a negative integer, or neither
|
217
|
+
if _self == Num(1)
|
218
|
+
return _self if context.exact?
|
219
|
+
if other.integral?
|
220
|
+
# exp = max(self._exp*max(int(other), 0),
|
221
|
+
# 1-context.prec) but evaluating int(other) directly
|
222
|
+
# is dangerous until we know other is small (other
|
223
|
+
# could be 1e999999999)
|
224
|
+
if other.sign == -1
|
225
|
+
multiplier = 0
|
226
|
+
elsif other > context.precision
|
227
|
+
multiplier = context.precision
|
228
|
+
else
|
229
|
+
multiplier = other.to_i
|
230
|
+
end
|
231
|
+
|
232
|
+
exp = _self.exponent * multiplier
|
233
|
+
if exp < 1-context.precision
|
234
|
+
exp = 1-context.precision
|
235
|
+
context.exception Rounded
|
236
|
+
end
|
237
|
+
else
|
238
|
+
context.exception Rounded
|
239
|
+
context.exception Inexact
|
240
|
+
exp = 1-context.precision
|
241
|
+
end
|
242
|
+
|
243
|
+
return Num(result_sign, DecNum.int_radix_power(-exp), exp)
|
244
|
+
end
|
245
|
+
|
246
|
+
# compute adjusted exponent of self
|
247
|
+
self_adj = _self.adjusted_exponent
|
248
|
+
|
249
|
+
# self ** infinity is infinity if self > 1, 0 if self < 1
|
250
|
+
# self ** -infinity is infinity if self < 1, 0 if self > 1
|
251
|
+
if other.infinite?
|
252
|
+
if (other.sign == +1) == (self_adj < 0)
|
253
|
+
return Num(result_sign, 0, 0)
|
254
|
+
else
|
255
|
+
return DecNum.infinity(result_sign)
|
256
|
+
end
|
257
|
+
end
|
258
|
+
|
259
|
+
# from here on, the result always goes through the call
|
260
|
+
# to _fix at the end of this function.
|
261
|
+
ans = nil
|
262
|
+
|
263
|
+
# crude test to catch cases of extreme overflow/underflow. If
|
264
|
+
# log10(self)*other >= 10**bound and bound >= len(str(Emax))
|
265
|
+
# then 10**bound >= 10**len(str(Emax)) >= Emax+1 and hence
|
266
|
+
# self**other >= 10**(Emax+1), so overflow occurs. The test
|
267
|
+
# for underflow is similar.
|
268
|
+
bound = _self._log10_exp_bound + other.adjusted_exponent
|
269
|
+
if (self_adj >= 0) == (other.sign == +1)
|
270
|
+
# self > 1 and other +ve, or self < 1 and other -ve
|
271
|
+
# possibility of overflow
|
272
|
+
if bound >= _number_of_digits(context.emax)
|
273
|
+
ans = Num(result_sign, 1, context.emax+1)
|
274
|
+
end
|
275
|
+
else
|
276
|
+
# self > 1 and other -ve, or self < 1 and other +ve
|
277
|
+
# possibility of underflow to 0
|
278
|
+
etiny = context.etiny
|
279
|
+
if bound >= _number_of_digits(-etiny)
|
280
|
+
ans = Num(result_sign, 1, etiny-1)
|
281
|
+
end
|
282
|
+
end
|
283
|
+
|
284
|
+
# try for an exact result with precision +1
|
285
|
+
if ans.nil?
|
286
|
+
if context.exact?
|
287
|
+
if other.adjusted_exponent < 100
|
288
|
+
test_precision = _self.number_of_digits*other.to_i+1
|
289
|
+
else
|
290
|
+
test_precision = _self.number_of_digits+1
|
291
|
+
end
|
292
|
+
else
|
293
|
+
test_precision = context.precision + 1
|
294
|
+
end
|
295
|
+
ans = _self._power_exact(other, test_precision)
|
296
|
+
if !ans.nil? && (result_sign == -1)
|
297
|
+
ans = Num(-1, ans.coefficient, ans.exponent)
|
298
|
+
end
|
299
|
+
end
|
300
|
+
|
301
|
+
# usual case: inexact result, x**y computed directly as exp(y*log(x))
|
302
|
+
if !ans.nil?
|
303
|
+
return ans if context.exact?
|
304
|
+
else
|
305
|
+
return context.exception(Inexact, "Inexact power") if context.exact?
|
306
|
+
|
307
|
+
p = context.precision
|
308
|
+
xc = _self.coefficient
|
309
|
+
xe = _self.exponent
|
310
|
+
yc = other.coefficient
|
311
|
+
ye = other.exponent
|
312
|
+
yc = -yc if other.sign == -1
|
313
|
+
|
314
|
+
# compute correctly rounded result: start with precision +3,
|
315
|
+
# then increase precision until result is unambiguously roundable
|
316
|
+
extra = 3
|
317
|
+
coeff, exp = nil, nil
|
318
|
+
loop do
|
319
|
+
coeff, exp = _dpower(xc, xe, yc, ye, p+extra)
|
320
|
+
#break if (coeff % DecNum.int_mult_radix_power(5,coeff.to_s.length-p-1)) != 0
|
321
|
+
break if (coeff % (5*10**(_number_of_digits(coeff)-p-1))) != 0
|
322
|
+
extra += 3
|
323
|
+
end
|
324
|
+
ans = Num(result_sign, coeff, exp)
|
325
|
+
end
|
326
|
+
|
327
|
+
# the specification says that for non-integer other we need to
|
328
|
+
# raise Inexact, even when the result is actually exact. In
|
329
|
+
# the same way, we need to raise Underflow here if the result
|
330
|
+
# is subnormal. (The call to _fix will take care of raising
|
331
|
+
# Rounded and Subnormal, as usual.)
|
332
|
+
if !other.integral?
|
333
|
+
context.exception Inexact
|
334
|
+
# pad with zeros up to length context.precision+1 if necessary
|
335
|
+
if ans.number_of_digits <= context.precision
|
336
|
+
expdiff = context.precision+1 - ans.number_of_digits
|
337
|
+
ans = Num(ans.sign, DecNum.int_mult_radix_power(ans.coefficient, expdiff), ans.exponent-expdiff)
|
338
|
+
end
|
339
|
+
context.exception Underflow if ans.adjusted_exponent < context.emin
|
340
|
+
end
|
341
|
+
# unlike exp, ln and log10, the power function respects the
|
342
|
+
# rounding mode; no need to use ROUND_HALF_EVEN here
|
343
|
+
ans._fix(context)
|
344
|
+
end
|
345
|
+
|
346
|
+
# Returns the base 10 logarithm
|
347
|
+
def log10(context=nil)
|
348
|
+
context = DecNum.define_context(context)
|
349
|
+
|
350
|
+
# log10(NaN) = NaN
|
351
|
+
ans = _check_nans(context)
|
352
|
+
return ans if ans
|
353
|
+
|
354
|
+
# log10(0.0) == -Infinity
|
355
|
+
return DecNum.infinity(-1) if self.zero?
|
356
|
+
|
357
|
+
# log10(Infinity) = Infinity
|
358
|
+
return DecNum.infinity if self.infinite? && self.sign == +1
|
359
|
+
|
360
|
+
# log10(negative or -Infinity) raises InvalidOperation
|
361
|
+
return context.exception(InvalidOperation, 'log10 of a negative value') if self.sign == -1
|
362
|
+
|
363
|
+
digits = self.digits
|
364
|
+
# log10(10**n) = n
|
365
|
+
if digits.first == 1 && digits[1..-1].all?{|d| d==0}
|
366
|
+
# answer may need rounding
|
367
|
+
ans = Num(self.exponent + digits.size - 1)
|
368
|
+
return ans if context.exact?
|
369
|
+
else
|
370
|
+
# result is irrational, so necessarily inexact
|
371
|
+
return context.exception(Inexact, "Inexact power") if context.exact?
|
372
|
+
c = self.coefficient
|
373
|
+
e = self.exponent
|
374
|
+
p = context.precision
|
375
|
+
|
376
|
+
# correctly rounded result: repeatedly increase precision
|
377
|
+
# until result is unambiguously roundable
|
378
|
+
places = p-self._log10_exp_bound+2
|
379
|
+
coeff = nil
|
380
|
+
loop do
|
381
|
+
coeff = _dlog10(c, e, places)
|
382
|
+
# assert coeff.abs.to_s.length-p >= 1
|
383
|
+
break if (coeff % (5*10**(_number_of_digits(coeff.abs)-p-1)))!=0
|
384
|
+
places += 3
|
385
|
+
end
|
386
|
+
ans = Num(coeff<0 ? -1 : +1, coeff.abs, -places)
|
387
|
+
end
|
388
|
+
|
389
|
+
DecNum.context(context, :rounding=>:half_even) do |local_context|
|
390
|
+
ans = ans._fix(local_context)
|
391
|
+
context.flags = local_context.flags
|
392
|
+
end
|
393
|
+
return ans
|
394
|
+
end
|
395
|
+
|
396
|
+
# Exponential function
|
397
|
+
def exp(context=nil)
|
398
|
+
context = DecNum.define_context(context)
|
399
|
+
|
400
|
+
# exp(NaN) = NaN
|
401
|
+
ans = _check_nans(context)
|
402
|
+
return ans if ans
|
403
|
+
|
404
|
+
# exp(-Infinity) = 0
|
405
|
+
return DecNum.zero if self.infinite? && (self.sign == -1)
|
406
|
+
|
407
|
+
# exp(0) = 1
|
408
|
+
return Num(1) if self.zero?
|
409
|
+
|
410
|
+
# exp(Infinity) = Infinity
|
411
|
+
return Num(self) if self.infinite?
|
412
|
+
|
413
|
+
# the result is now guaranteed to be inexact (the true
|
414
|
+
# mathematical result is transcendental). There's no need to
|
415
|
+
# raise Rounded and Inexact here---they'll always be raised as
|
416
|
+
# a result of the call to _fix.
|
417
|
+
return context.exception(Inexact, 'Inexact exp') if context.exact?
|
418
|
+
p = context.precision
|
419
|
+
adj = self.adjusted_exponent
|
420
|
+
|
421
|
+
# we only need to do any computation for quite a small range
|
422
|
+
# of adjusted exponents---for example, -29 <= adj <= 10 for
|
423
|
+
# the default context. For smaller exponent the result is
|
424
|
+
# indistinguishable from 1 at the given precision, while for
|
425
|
+
# larger exponent the result either overflows or underflows.
|
426
|
+
if self.sign == +1 and adj > _number_of_digits((context.emax+1)*3)
|
427
|
+
# overflow
|
428
|
+
ans = Num(+1, 1, context.emax+1)
|
429
|
+
elsif self.sign == -1 and adj > _number_of_digits((-context.etiny+1)*3)
|
430
|
+
# underflow to 0
|
431
|
+
ans = Num(+1, 1, context.etiny-1)
|
432
|
+
elsif self.sign == +1 and adj < -p
|
433
|
+
# p+1 digits; final round will raise correct flags
|
434
|
+
ans = Num(+1, DecNum.int_radix_power(p)+1, -p)
|
435
|
+
elsif self.sign == -1 and adj < -p-1
|
436
|
+
# p+1 digits; final round will raise correct flags
|
437
|
+
ans = Num(+1, DecNum.int_radix_power(p+1)-1, -p-1)
|
438
|
+
else
|
439
|
+
# general case
|
440
|
+
c = self.coefficient
|
441
|
+
e = self.exponent
|
442
|
+
c = -c if self.sign == -1
|
443
|
+
|
444
|
+
# compute correctly rounded result: increase precision by
|
445
|
+
# 3 digits at a time until we get an unambiguously
|
446
|
+
# roundable result
|
447
|
+
extra = 3
|
448
|
+
coeff = exp = nil
|
449
|
+
loop do
|
450
|
+
coeff, exp = _dexp(c, e, p+extra)
|
451
|
+
break if (coeff % (5*10**(_number_of_digits(coeff)-p-1)))!=0
|
452
|
+
extra += 3
|
453
|
+
end
|
454
|
+
ans = Num(+1, coeff, exp)
|
455
|
+
end
|
456
|
+
|
457
|
+
# at this stage, ans should round correctly with *any*
|
458
|
+
# rounding mode, not just with ROUND_HALF_EVEN
|
459
|
+
DecNum.context(context, :rounding=>:half_even) do |local_context|
|
460
|
+
ans = ans._fix(local_context)
|
461
|
+
context.flags = local_context.flags
|
462
|
+
end
|
463
|
+
|
464
|
+
return ans
|
465
|
+
end
|
466
|
+
|
467
|
+
# Returns the natural (base e) logarithm
|
468
|
+
def ln(context=nil)
|
469
|
+
context = DecNum.define_context(context)
|
470
|
+
|
471
|
+
# ln(NaN) = NaN
|
472
|
+
ans = _check_nans(context)
|
473
|
+
return ans if ans
|
474
|
+
|
475
|
+
# ln(0.0) == -Infinity
|
476
|
+
return DecNum.infinity(-1) if self.zero?
|
477
|
+
|
478
|
+
# ln(Infinity) = Infinity
|
479
|
+
return DecNum.infinity if self.infinite? && self.sign == +1
|
480
|
+
|
481
|
+
# ln(1.0) == 0.0
|
482
|
+
return DecNum.zero if self == Num(1)
|
483
|
+
|
484
|
+
# ln(negative) raises InvalidOperation
|
485
|
+
return context.exception(InvalidOperation, 'ln of a negative value') if self.sign==-1
|
486
|
+
|
487
|
+
# result is irrational, so necessarily inexact
|
488
|
+
return context.exception(Inexact, 'Inexact exp') if context.exact?
|
489
|
+
|
490
|
+
c = self.coefficient
|
491
|
+
e = self.exponent
|
492
|
+
p = context.precision
|
493
|
+
|
494
|
+
# correctly rounded result: repeatedly increase precision by 3
|
495
|
+
# until we get an unambiguously roundable result
|
496
|
+
places = p - self._ln_exp_bound + 2 # at least p+3 places
|
497
|
+
coeff = nil
|
498
|
+
loop do
|
499
|
+
coeff = _dlog(c, e, places)
|
500
|
+
# assert coeff.to_s.length-p >= 1
|
501
|
+
break if (coeff % (5*10**(_number_of_digits(coeff.abs)-p-1))) != 0
|
502
|
+
places += 3
|
503
|
+
end
|
504
|
+
ans = Num((coeff<0) ? -1 : +1, coeff.abs, -places)
|
505
|
+
|
506
|
+
DecNum.context(context, :rounding=>:half_even) do |local_context|
|
507
|
+
ans = ans._fix(local_context)
|
508
|
+
context.flags = local_context.flags
|
509
|
+
end
|
510
|
+
return ans
|
511
|
+
end
|
512
|
+
|
513
|
+
# Auxiliar Methods
|
514
|
+
|
515
|
+
|
516
|
+
|
517
|
+
# Power-modulo: self._power_modulo(other, modulo) == (self**other) % modulo
|
518
|
+
# This is equivalent to Python's 3-argument version of pow()
|
519
|
+
def _power_modulo(other, modulo, context=nil)
|
520
|
+
|
521
|
+
context = DecNum.define_context(context)
|
522
|
+
other = _convert(other)
|
523
|
+
modulo = _convert(third)
|
524
|
+
|
525
|
+
if self.nan? || other.nan? || modulo.nan?
|
526
|
+
return context.exception(InvalidOperation, 'sNaN', self) if self.snan?
|
527
|
+
return context.exception(InvalidOperation, 'sNaN', other) if other.snan?
|
528
|
+
return context.exception(InvalidOperation, 'sNaN', modulo) if other.modulo?
|
529
|
+
return self._fix_nan(context) if self.nan?
|
530
|
+
return other._fix_nan(context) if other.nan?
|
531
|
+
return modulo._fix_nan(context) # if modulo.nan?
|
532
|
+
end
|
533
|
+
|
534
|
+
if !(self.integral? && other.integral? && modulo.integral?)
|
535
|
+
return context.exception(InvalidOperation, '3-argument power not allowed unless all arguments are integers.')
|
536
|
+
end
|
537
|
+
|
538
|
+
if other < 0
|
539
|
+
return context.exception(InvalidOperation, '3-argument power cannot have a negative 2nd argument.')
|
540
|
+
end
|
541
|
+
|
542
|
+
if modulo.zero?
|
543
|
+
return context.exception(InvalidOperation, '3-argument power cannot have a 0 3rd argument.')
|
544
|
+
end
|
545
|
+
|
546
|
+
if modulo.adjusted_exponent >= context.precision
|
547
|
+
return context.exception(InvalidOperation, 'insufficient precision: power 3rd argument must not have more than precision digits')
|
548
|
+
end
|
549
|
+
|
550
|
+
if other.zero? && self.zero?
|
551
|
+
return context.exception(InvalidOperation, "0**0 not defined")
|
552
|
+
end
|
553
|
+
|
554
|
+
sign = other.even? ? +1 : -1
|
555
|
+
modulo = modulo.to_i.abs
|
556
|
+
|
557
|
+
base = (self.coefficient % modulo * (DecNum.int_radix_power(self.exponent) % modulo)) % modulo
|
558
|
+
|
559
|
+
other.exponent.times do
|
560
|
+
base = (base**DecNum.radix) % modulo
|
561
|
+
end
|
562
|
+
base = (base**other.coefficient) % modulo
|
563
|
+
|
564
|
+
Num(sign, base, 0)
|
565
|
+
end
|
566
|
+
|
567
|
+
# Attempt to compute self**other exactly
|
568
|
+
# Given Decimals self and other and an integer p, attempt to
|
569
|
+
# compute an exact result for the power self**other, with p
|
570
|
+
# digits of precision. Return nil if self**other is not
|
571
|
+
# exactly representable in p digits.
|
572
|
+
#
|
573
|
+
# Assumes that elimination of special cases has already been
|
574
|
+
# performed: self and other must both be nonspecial; self must
|
575
|
+
# be positive and not numerically equal to 1; other must be
|
576
|
+
# nonzero. For efficiency, other.exponent should not be too large,
|
577
|
+
# so that 10**other.exponent.abs is a feasible calculation.
|
578
|
+
def _power_exact(other, p)
|
579
|
+
|
580
|
+
# In the comments below, we write x for the value of self and
|
581
|
+
# y for the value of other. Write x = xc*10**xe and y =
|
582
|
+
# yc*10**ye.
|
583
|
+
|
584
|
+
# The main purpose of this method is to identify the *failure*
|
585
|
+
# of x**y to be exactly representable with as little effort as
|
586
|
+
# possible. So we look for cheap and easy tests that
|
587
|
+
# eliminate the possibility of x**y being exact. Only if all
|
588
|
+
# these tests are passed do we go on to actually compute x**y.
|
589
|
+
|
590
|
+
# Here's the main idea. First normalize both x and y. We
|
591
|
+
# express y as a rational m/n, with m and n relatively prime
|
592
|
+
# and n>0. Then for x**y to be exactly representable (at
|
593
|
+
# *any* precision), xc must be the nth power of a positive
|
594
|
+
# integer and xe must be divisible by n. If m is negative
|
595
|
+
# then additionally xc must be a power of either 2 or 5, hence
|
596
|
+
# a power of 2**n or 5**n.
|
597
|
+
#
|
598
|
+
# There's a limit to how small |y| can be: if y=m/n as above
|
599
|
+
# then:
|
600
|
+
#
|
601
|
+
# (1) if xc != 1 then for the result to be representable we
|
602
|
+
# need xc**(1/n) >= 2, and hence also xc**|y| >= 2. So
|
603
|
+
# if |y| <= 1/nbits(xc) then xc < 2**nbits(xc) <=
|
604
|
+
# 2**(1/|y|), hence xc**|y| < 2 and the result is not
|
605
|
+
# representable.
|
606
|
+
#
|
607
|
+
# (2) if xe != 0, |xe|*(1/n) >= 1, so |xe|*|y| >= 1. Hence if
|
608
|
+
# |y| < 1/|xe| then the result is not representable.
|
609
|
+
#
|
610
|
+
# Note that since x is not equal to 1, at least one of (1) and
|
611
|
+
# (2) must apply. Now |y| < 1/nbits(xc) iff |yc|*nbits(xc) <
|
612
|
+
# 10**-ye iff len(str(|yc|*nbits(xc)) <= -ye.
|
613
|
+
#
|
614
|
+
# There's also a limit to how large y can be, at least if it's
|
615
|
+
# positive: the normalized result will have coefficient xc**y,
|
616
|
+
# so if it's representable then xc**y < 10**p, and y <
|
617
|
+
# p/log10(xc). Hence if y*log10(xc) >= p then the result is
|
618
|
+
# not exactly representable.
|
619
|
+
|
620
|
+
# if len(str(abs(yc*xe)) <= -ye then abs(yc*xe) < 10**-ye,
|
621
|
+
# so |y| < 1/xe and the result is not representable.
|
622
|
+
# Similarly, len(str(abs(yc)*xc_bits)) <= -ye implies |y|
|
623
|
+
# < 1/nbits(xc).
|
624
|
+
|
625
|
+
xc = self.coefficient
|
626
|
+
xe = self.exponent
|
627
|
+
while (xc % DecNum.radix) == 0
|
628
|
+
xc /= DecNum.radix
|
629
|
+
xe += 1
|
630
|
+
end
|
631
|
+
|
632
|
+
yc = other.coefficient
|
633
|
+
ye = other.exponent
|
634
|
+
while (yc % DecNum.radix) == 0
|
635
|
+
yc /= DecNum.radix
|
636
|
+
ye += 1
|
637
|
+
end
|
638
|
+
|
639
|
+
# case where xc == 1: result is 10**(xe*y), with xe*y
|
640
|
+
# required to be an integer
|
641
|
+
if xc == 1
|
642
|
+
if ye >= 0
|
643
|
+
exponent = xe*yc*DecNum.int_radix_power(ye)
|
644
|
+
else
|
645
|
+
exponent, remainder = (xe*yc).divmod(DecNum.int_radix_power(-ye))
|
646
|
+
return nil if remainder!=0
|
647
|
+
end
|
648
|
+
exponent = -exponent if other.sign == -1
|
649
|
+
# if other is a nonnegative integer, use ideal exponent
|
650
|
+
if other.integral? and (other.sign == +1)
|
651
|
+
ideal_exponent = self.exponent*other.to_i
|
652
|
+
zeros = [exponent-ideal_exponent, p-1].min
|
653
|
+
else
|
654
|
+
zeros = 0
|
655
|
+
end
|
656
|
+
return Num(+1, DecNum.int_radix_power(zeros), exponent-zeros)
|
657
|
+
end
|
658
|
+
|
659
|
+
# case where y is negative: xc must be either a power
|
660
|
+
# of 2 or a power of 5.
|
661
|
+
if other.sign == -1
|
662
|
+
last_digit = (xc % 10)
|
663
|
+
if [2,4,6,8].include?(last_digit)
|
664
|
+
# quick test for power of 2
|
665
|
+
return nil if xc & -xc != xc
|
666
|
+
# now xc is a power of 2; e is its exponent
|
667
|
+
e = _nbits(xc)-1
|
668
|
+
# find e*y and xe*y; both must be integers
|
669
|
+
if ye >= 0
|
670
|
+
y_as_int = yc*DecNum.int_radix_power(ye)
|
671
|
+
e = e*y_as_int
|
672
|
+
xe = xe*y_as_int
|
673
|
+
else
|
674
|
+
ten_pow = DecNum.int_radix_power(-ye)
|
675
|
+
e, remainder = (e*yc).divmod(ten_pow)
|
676
|
+
return nil if remainder!=0
|
677
|
+
xe, remainder = (xe*yc).divmod(ten_pow)
|
678
|
+
return nil if remainder!=0
|
679
|
+
end
|
680
|
+
|
681
|
+
return nil if e*65 >= p*93 # 93/65 > log(10)/log(5)
|
682
|
+
xc = 5**e
|
683
|
+
elsif last_digit == 5
|
684
|
+
# e >= log_5(xc) if xc is a power of 5; we have
|
685
|
+
# equality all the way up to xc=5**2658
|
686
|
+
e = _nbits(xc)*28/65
|
687
|
+
xc, remainder = (5**e).divmod(xc)
|
688
|
+
return nil if remainder!=0
|
689
|
+
while (xc % 5) == 0
|
690
|
+
xc /= 5
|
691
|
+
e -= 1
|
692
|
+
end
|
693
|
+
if ye >= 0
|
694
|
+
y_as_integer = DecNum.int_mult_radix_power(yc,ye)
|
695
|
+
e = e*y_as_integer
|
696
|
+
xe = xe*y_as_integer
|
697
|
+
else
|
698
|
+
ten_pow = DecNum.int_radix_power(-ye)
|
699
|
+
e, remainder = (e*yc).divmod(ten_pow)
|
700
|
+
return nil if remainder
|
701
|
+
xe, remainder = (xe*yc).divmod(ten_pow)
|
702
|
+
return nil if remainder
|
703
|
+
end
|
704
|
+
return nil if e*3 >= p*10 # 10/3 > log(10)/log(2)
|
705
|
+
xc = 2**e
|
706
|
+
else
|
707
|
+
return nil
|
708
|
+
end
|
709
|
+
|
710
|
+
return nil if xc >= DecNum.int_radix_power(p)
|
711
|
+
xe = -e-xe
|
712
|
+
return Num(+1, xc, xe)
|
713
|
+
|
714
|
+
end
|
715
|
+
|
716
|
+
# now y is positive; find m and n such that y = m/n
|
717
|
+
if ye >= 0
|
718
|
+
m, n = yc*10**ye, 1
|
719
|
+
else
|
720
|
+
return nil if (xe != 0) and (_number_of_digits((yc*xe).abs) <= -ye)
|
721
|
+
xc_bits = _nbits(xc)
|
722
|
+
return nil if (xc != 1) and (_number_of_digits(yc.abs*xc_bits) <= -ye)
|
723
|
+
m, n = yc, DecNum.int_radix_power(-ye)
|
724
|
+
while ((m % 2) == 0) && ((n % 2) == 0)
|
725
|
+
m /= 2
|
726
|
+
n /= 2
|
727
|
+
end
|
728
|
+
while ((m % 5) == 0) && ((n % 5) == 0)
|
729
|
+
m /= 5
|
730
|
+
n /= 5
|
731
|
+
end
|
732
|
+
end
|
733
|
+
|
734
|
+
# compute nth root of xc*10**xe
|
735
|
+
if n > 1
|
736
|
+
# if 1 < xc < 2**n then xc isn't an nth power
|
737
|
+
return nil if xc != 1 and xc_bits <= n
|
738
|
+
|
739
|
+
xe, rem = xe.divmod(n)
|
740
|
+
return nil if rem != 0
|
741
|
+
|
742
|
+
# compute nth root of xc using Newton's method
|
743
|
+
a = 1 << -(-_nbits(xc)/n) # initial estimate
|
744
|
+
q = r = nil
|
745
|
+
loop do
|
746
|
+
q, r = xc.divmod(a**(n-1))
|
747
|
+
break if a <= q
|
748
|
+
a = (a*(n-1) + q)/n
|
749
|
+
end
|
750
|
+
return nil if !((a == q) and (r == 0))
|
751
|
+
xc = a
|
752
|
+
end
|
753
|
+
|
754
|
+
# now xc*10**xe is the nth root of the original xc*10**xe
|
755
|
+
# compute mth power of xc*10**xe
|
756
|
+
|
757
|
+
# if m > p*100/_log10_lb(xc) then m > p/log10(xc), hence xc**m >
|
758
|
+
# 10**p and the result is not representable.
|
759
|
+
return nil if (xc > 1) and (m > p*100/_log10_lb(xc))
|
760
|
+
xc = xc**m
|
761
|
+
xe *= m
|
762
|
+
return nil if xc > 10**p
|
763
|
+
|
764
|
+
# by this point the result *is* exactly representable
|
765
|
+
# adjust the exponent to get as close as possible to the ideal
|
766
|
+
# exponent, if necessary
|
767
|
+
if other.integral? && other.sign == +1
|
768
|
+
ideal_exponent = self.exponent*other.to_i
|
769
|
+
zeros = [xe-ideal_exponent, p-_number_of_digits(xc)].min
|
770
|
+
else
|
771
|
+
zeros = 0
|
772
|
+
end
|
773
|
+
return Num(+1, DecNum.int_mult_radix_power(xc, zeros), xe-zeros)
|
774
|
+
end
|
775
|
+
|
776
|
+
# Compute a lower bound for the adjusted exponent of self.log10()
|
777
|
+
# In other words, find r such that self.log10() >= 10**r.
|
778
|
+
# Assumes that self is finite and positive and that self != 1.
|
779
|
+
def _log10_exp_bound
|
780
|
+
# For x >= 10 or x < 0.1 we only need a bound on the integer
|
781
|
+
# part of log10(self), and this comes directly from the
|
782
|
+
# exponent of x. For 0.1 <= x <= 10 we use the inequalities
|
783
|
+
# 1-1/x <= log(x) <= x-1. If x > 1 we have |log10(x)| >
|
784
|
+
# (1-1/x)/2.31 > 0. If x < 1 then |log10(x)| > (1-x)/2.31 > 0
|
785
|
+
#
|
786
|
+
# The original Python cod used lexical order (having converted to strings) for (num < den) and (num < 231)
|
787
|
+
# so the results would be different e.g. for num = 9; Can this happen? What is the correct way?
|
788
|
+
|
789
|
+
adj = self.exponent + number_of_digits - 1
|
790
|
+
return _number_of_digits(adj) - 1 if adj >= 1 # self >= 10
|
791
|
+
return _number_of_digits(-1-adj)-1 if adj <= -2 # self < 0.1
|
792
|
+
|
793
|
+
c = self.coefficient
|
794
|
+
e = self.exponent
|
795
|
+
if adj == 0
|
796
|
+
# 1 < self < 10
|
797
|
+
num = (c - DecNum.int_radix_power(-e))
|
798
|
+
den = (231*c)
|
799
|
+
return _number_of_digits(num) - _number_of_digits(den) - ((num < den) ? 1 : 0) + 2
|
800
|
+
end
|
801
|
+
# adj == -1, 0.1 <= self < 1
|
802
|
+
num = (DecNum.int_radix_power(-e)-c)
|
803
|
+
return _number_of_digits(num.to_i) + e - ((num < 231) ? 1 : 0) - 1
|
804
|
+
end
|
805
|
+
|
806
|
+
# Compute a lower bound for the adjusted exponent of self.ln().
|
807
|
+
# In other words, compute r such that self.ln() >= 10**r. Assumes
|
808
|
+
# that self is finite and positive and that self != 1.
|
809
|
+
def _ln_exp_bound
|
810
|
+
# for 0.1 <= x <= 10 we use the inequalities 1-1/x <= ln(x) <= x-1
|
811
|
+
#
|
812
|
+
# The original Python cod used lexical order (having converted to strings) for (num < den))
|
813
|
+
# so the results would be different e.g. for num = 9m den=200; Can this happen? What is the correct way?
|
814
|
+
|
815
|
+
adj = self.exponent + number_of_digits - 1
|
816
|
+
if adj >= 1
|
817
|
+
# argument >= 10; we use 23/10 = 2.3 as a lower bound for ln(10)
|
818
|
+
return _number_of_digits(adj*23/10) - 1
|
819
|
+
end
|
820
|
+
if adj <= -2
|
821
|
+
# argument <= 0.1
|
822
|
+
return _number_of_digits((-1-adj)*23/10) - 1
|
823
|
+
end
|
824
|
+
c = self.coefficient
|
825
|
+
e = self.exponent
|
826
|
+
if adj == 0
|
827
|
+
# 1 < self < 10
|
828
|
+
num = c-(10**-e)
|
829
|
+
den = c
|
830
|
+
return _number_of_digits(num) - _number_of_digits(den) - ((num < den) ? 1 : 0)
|
831
|
+
end
|
832
|
+
# adj == -1, 0.1 <= self < 1
|
833
|
+
return e + _number_of_digits(10**-e - c) - 1
|
834
|
+
end
|
835
|
+
|
836
|
+
module AuxiliarFunctions #:nodoc:
|
837
|
+
|
838
|
+
module_function
|
839
|
+
|
840
|
+
# Given integers xc, xe, yc and ye representing Decimals x = xc*10**xe and
|
841
|
+
# y = yc*10**ye, compute x**y. Returns a pair of integers (c, e) such that:
|
842
|
+
#
|
843
|
+
# 10**(p-1) <= c <= 10**p, and
|
844
|
+
# (c-1)*10**e < x**y < (c+1)*10**e
|
845
|
+
#
|
846
|
+
# in other words, c*10**e is an approximation to x**y with p digits
|
847
|
+
# of precision, and with an error in c of at most 1. (This is
|
848
|
+
# almost, but not quite, the same as the error being < 1ulp: when c
|
849
|
+
# == 10**(p-1) we can only guarantee error < 10ulp.)
|
850
|
+
#
|
851
|
+
# We assume that: x is positive and not equal to 1, and y is nonzero.
|
852
|
+
def _dpower(xc, xe, yc, ye, p)
|
853
|
+
# Find b such that 10**(b-1) <= |y| <= 10**b
|
854
|
+
b = _number_of_digits(yc.abs) + ye
|
855
|
+
|
856
|
+
# log(x) = lxc*10**(-p-b-1), to p+b+1 places after the decimal point
|
857
|
+
lxc = _dlog(xc, xe, p+b+1)
|
858
|
+
|
859
|
+
# compute product y*log(x) = yc*lxc*10**(-p-b-1+ye) = pc*10**(-p-1)
|
860
|
+
shift = ye-b
|
861
|
+
if shift >= 0
|
862
|
+
pc = lxc*yc*10**shift
|
863
|
+
else
|
864
|
+
pc = _div_nearest(lxc*yc, 10**-shift)
|
865
|
+
end
|
866
|
+
|
867
|
+
if pc == 0
|
868
|
+
# we prefer a result that isn't exactly 1; this makes it
|
869
|
+
# easier to compute a correctly rounded result in __pow__
|
870
|
+
if (_number_of_digits(xc) + xe >= 1) == (yc > 0) # if x**y > 1:
|
871
|
+
coeff, exp = 10**(p-1)+1, 1-p
|
872
|
+
else
|
873
|
+
coeff, exp = 10**p-1, -p
|
874
|
+
end
|
875
|
+
else
|
876
|
+
coeff, exp = _dexp(pc, -(p+1), p+1)
|
877
|
+
coeff = _div_nearest(coeff, 10)
|
878
|
+
exp += 1
|
879
|
+
end
|
880
|
+
|
881
|
+
return coeff, exp
|
882
|
+
end
|
883
|
+
|
884
|
+
# Compute an approximation to exp(c*10**e), with p decimal places of precision.
|
885
|
+
# Returns integers d, f such that:
|
886
|
+
#
|
887
|
+
# 10**(p-1) <= d <= 10**p, and
|
888
|
+
# (d-1)*10**f < exp(c*10**e) < (d+1)*10**f
|
889
|
+
#
|
890
|
+
# In other words, d*10**f is an approximation to exp(c*10**e) with p
|
891
|
+
# digits of precision, and with an error in d of at most 1. This is
|
892
|
+
# almost, but not quite, the same as the error being < 1ulp: when d
|
893
|
+
# = 10**(p-1) the error could be up to 10 ulp.
|
894
|
+
def _dexp(c, e, p)
|
895
|
+
# we'll call iexp with M = 10**(p+2), giving p+3 digits of precision
|
896
|
+
p += 2
|
897
|
+
|
898
|
+
# compute log(10) with extra precision = adjusted exponent of c*10**e
|
899
|
+
# TODO: without the .abs tests fail because c is negative: c should not be negative!!
|
900
|
+
extra = [0, e + _number_of_digits(c.abs) - 1].max
|
901
|
+
q = p + extra
|
902
|
+
|
903
|
+
# compute quotient c*10**e/(log(10)) = c*10**(e+q)/(log(10)*10**q),
|
904
|
+
# rounding down
|
905
|
+
shift = e+q
|
906
|
+
if shift >= 0
|
907
|
+
cshift = c*10**shift
|
908
|
+
else
|
909
|
+
cshift = c/10**-shift
|
910
|
+
end
|
911
|
+
quot, rem = cshift.divmod(_log10_digits(q))
|
912
|
+
|
913
|
+
# reduce remainder back to original precision
|
914
|
+
rem = _div_nearest(rem, 10**extra)
|
915
|
+
|
916
|
+
# error in result of _iexp < 120; error after division < 0.62
|
917
|
+
return _div_nearest(_iexp(rem, 10**p), 1000), quot - p + 3
|
918
|
+
end
|
919
|
+
|
920
|
+
# Closest integer to a/b, a and b positive integers; rounds to even
|
921
|
+
# in the case of a tie.
|
922
|
+
def _div_nearest(a, b)
|
923
|
+
q, r = a.divmod(b)
|
924
|
+
q + (((2*r + (q&1)) > b) ? 1 : 0)
|
925
|
+
end
|
926
|
+
|
927
|
+
# Closest integer to the square root of the positive integer n. a is
|
928
|
+
# an initial approximation to the square root. Any positive integer
|
929
|
+
# will do for a, but the closer a is to the square root of n the
|
930
|
+
# faster convergence will be.
|
931
|
+
def _sqrt_nearest(n, a)
|
932
|
+
|
933
|
+
if n <= 0 or a <= 0
|
934
|
+
raise ArgumentError, "Both arguments to _sqrt_nearest should be positive."
|
935
|
+
end
|
936
|
+
|
937
|
+
b=0
|
938
|
+
while a != b
|
939
|
+
b, a = a, a--n/a>>1 # ??
|
940
|
+
end
|
941
|
+
return a
|
942
|
+
end
|
943
|
+
|
944
|
+
# Given an integer x and a nonnegative integer shift, return closest
|
945
|
+
# integer to x / 2**shift; use round-to-even in case of a tie.
|
946
|
+
def _rshift_nearest(x, shift)
|
947
|
+
b, q = (1 << shift), (x >> shift)
|
948
|
+
return q + (((2*(x & (b-1)) + (q&1)) > b) ? 1 : 0)
|
949
|
+
#return q + (2*(x & (b-1)) + (((q&1) > b) ? 1 : 0))
|
950
|
+
end
|
951
|
+
|
952
|
+
# Integer approximation to M*log(x/M), with absolute error boundable
|
953
|
+
# in terms only of x/M.
|
954
|
+
#
|
955
|
+
# Given positive integers x and M, return an integer approximation to
|
956
|
+
# M * log(x/M). For L = 8 and 0.1 <= x/M <= 10 the difference
|
957
|
+
# between the approximation and the exact result is at most 22. For
|
958
|
+
# L = 8 and 1.0 <= x/M <= 10.0 the difference is at most 15. In
|
959
|
+
# both cases these are upper bounds on the error; it will usually be
|
960
|
+
# much smaller.
|
961
|
+
def _ilog(x, m, l = 8)
|
962
|
+
# The basic algorithm is the following: let log1p be the function
|
963
|
+
# log1p(x) = log(1+x). Then log(x/M) = log1p((x-M)/M). We use
|
964
|
+
# the reduction
|
965
|
+
#
|
966
|
+
# log1p(y) = 2*log1p(y/(1+sqrt(1+y)))
|
967
|
+
#
|
968
|
+
# repeatedly until the argument to log1p is small (< 2**-L in
|
969
|
+
# absolute value). For small y we can use the Taylor series
|
970
|
+
# expansion
|
971
|
+
#
|
972
|
+
# log1p(y) ~ y - y**2/2 + y**3/3 - ... - (-y)**T/T
|
973
|
+
#
|
974
|
+
# truncating at T such that y**T is small enough. The whole
|
975
|
+
# computation is carried out in a form of fixed-point arithmetic,
|
976
|
+
# with a real number z being represented by an integer
|
977
|
+
# approximation to z*M. To avoid loss of precision, the y below
|
978
|
+
# is actually an integer approximation to 2**R*y*M, where R is the
|
979
|
+
# number of reductions performed so far.
|
980
|
+
|
981
|
+
y = x-m
|
982
|
+
# argument reduction; R = number of reductions performed
|
983
|
+
r = 0
|
984
|
+
# while (r <= l && y.abs << l-r >= m ||
|
985
|
+
# r > l and y.abs>> r-l >= m)
|
986
|
+
while (((r <= l) && ((y.abs << (l-r)) >= m)) ||
|
987
|
+
((r > l) && ((y.abs>>(r-l)) >= m)))
|
988
|
+
y = _div_nearest((m*y) << 1,
|
989
|
+
m + _sqrt_nearest(m*(m+_rshift_nearest(y, r)), m))
|
990
|
+
r += 1
|
991
|
+
end
|
992
|
+
|
993
|
+
# Taylor series with T terms
|
994
|
+
t = -(-10*_number_of_digits(m)/(3*l)).to_i
|
995
|
+
yshift = _rshift_nearest(y, r)
|
996
|
+
w = _div_nearest(m, t)
|
997
|
+
# (1...t).reverse_each do |k| # Ruby 1.9
|
998
|
+
(1...t).to_a.reverse.each do |k|
|
999
|
+
w = _div_nearest(m, k) - _div_nearest(yshift*w, m)
|
1000
|
+
end
|
1001
|
+
|
1002
|
+
return _div_nearest(w*y, m)
|
1003
|
+
end
|
1004
|
+
|
1005
|
+
# Given integers c, e and p with c > 0, p >= 0, compute an integer
|
1006
|
+
# approximation to 10**p * log10(c*10**e), with an absolute error of
|
1007
|
+
# at most 1. Assumes that c*10**e is not exactly 1.
|
1008
|
+
def _dlog10(c, e, p)
|
1009
|
+
# increase precision by 2; compensate for this by dividing
|
1010
|
+
# final result by 100
|
1011
|
+
p += 2
|
1012
|
+
|
1013
|
+
# write c*10**e as d*10**f with either:
|
1014
|
+
# f >= 0 and 1 <= d <= 10, or
|
1015
|
+
# f <= 0 and 0.1 <= d <= 1.
|
1016
|
+
# Thus for c*10**e close to 1, f = 0
|
1017
|
+
l = _number_of_digits(c)
|
1018
|
+
f = e+l - ((e+l >= 1) ? 1 : 0)
|
1019
|
+
|
1020
|
+
if p > 0
|
1021
|
+
m = 10**p
|
1022
|
+
k = e+p-f
|
1023
|
+
if k >= 0
|
1024
|
+
c *= 10**k
|
1025
|
+
else
|
1026
|
+
c = _div_nearest(c, 10**-k)
|
1027
|
+
end
|
1028
|
+
log_d = _ilog(c, m) # error < 5 + 22 = 27
|
1029
|
+
log_10 = _log10_digits(p) # error < 1
|
1030
|
+
log_d = _div_nearest(log_d*m, log_10)
|
1031
|
+
log_tenpower = f*m # exact
|
1032
|
+
else
|
1033
|
+
log_d = 0 # error < 2.31
|
1034
|
+
log_tenpower = _div_nearest(f, 10**-p) # error < 0.5
|
1035
|
+
end
|
1036
|
+
|
1037
|
+
return _div_nearest(log_tenpower+log_d, 100)
|
1038
|
+
end
|
1039
|
+
|
1040
|
+
# Compute a lower bound for 100*log10(c) for a positive integer c.
|
1041
|
+
def _log10_lb(c)
|
1042
|
+
raise ArgumentError, "The argument to _log10_lb should be nonnegative." if c <= 0
|
1043
|
+
str_c = c.to_s
|
1044
|
+
return 100*str_c.length - LOG10_LB_CORRECTION[str_c[0,1]]
|
1045
|
+
end
|
1046
|
+
LOG10_LB_CORRECTION = { # (1..9).map_hash{|i| 100 - (100*Math.log10(i)).floor}
|
1047
|
+
'1'=> 100, '2'=> 70, '3'=> 53, '4'=> 40, '5'=> 31,
|
1048
|
+
'6'=> 23, '7'=> 16, '8'=> 10, '9'=> 5}
|
1049
|
+
|
1050
|
+
# Given integers c, e and p with c > 0, compute an integer
|
1051
|
+
# approximation to 10**p * log(c*10**e), with an absolute error of
|
1052
|
+
# at most 1. Assumes that c*10**e is not exactly 1.
|
1053
|
+
def _dlog(c, e, p)
|
1054
|
+
|
1055
|
+
# Increase precision by 2. The precision increase is compensated
|
1056
|
+
# for at the end with a division by 100.
|
1057
|
+
p += 2
|
1058
|
+
|
1059
|
+
# rewrite c*10**e as d*10**f with either f >= 0 and 1 <= d <= 10,
|
1060
|
+
# or f <= 0 and 0.1 <= d <= 1. Then we can compute 10**p * log(c*10**e)
|
1061
|
+
# as 10**p * log(d) + 10**p*f * log(10).
|
1062
|
+
l = _number_of_digits(c)
|
1063
|
+
f = e+l - ((e+l >= 1) ? 1 : 0)
|
1064
|
+
|
1065
|
+
# compute approximation to 10**p*log(d), with error < 27
|
1066
|
+
if p > 0
|
1067
|
+
k = e+p-f
|
1068
|
+
if k >= 0
|
1069
|
+
c *= 10**k
|
1070
|
+
else
|
1071
|
+
c = _div_nearest(c, 10**-k) # error of <= 0.5 in c
|
1072
|
+
end
|
1073
|
+
|
1074
|
+
# _ilog magnifies existing error in c by a factor of at most 10
|
1075
|
+
log_d = _ilog(c, 10**p) # error < 5 + 22 = 27
|
1076
|
+
else
|
1077
|
+
# p <= 0: just approximate the whole thing by 0; error < 2.31
|
1078
|
+
log_d = 0
|
1079
|
+
end
|
1080
|
+
|
1081
|
+
# compute approximation to f*10**p*log(10), with error < 11.
|
1082
|
+
if f
|
1083
|
+
extra = _number_of_digits(f.abs) - 1
|
1084
|
+
if p + extra >= 0
|
1085
|
+
# error in f * _log10_digits(p+extra) < |f| * 1 = |f|
|
1086
|
+
# after division, error < |f|/10**extra + 0.5 < 10 + 0.5 < 11
|
1087
|
+
f_log_ten = _div_nearest(f*_log10_digits(p+extra), 10**extra)
|
1088
|
+
else
|
1089
|
+
f_log_ten = 0
|
1090
|
+
end
|
1091
|
+
else
|
1092
|
+
f_log_ten = 0
|
1093
|
+
end
|
1094
|
+
|
1095
|
+
# error in sum < 11+27 = 38; error after division < 0.38 + 0.5 < 1
|
1096
|
+
return _div_nearest(f_log_ten + log_d, 100)
|
1097
|
+
end
|
1098
|
+
|
1099
|
+
# Given integers x and M, M > 0, such that x/M is small in absolute
|
1100
|
+
# value, compute an integer approximation to M*exp(x/M). For 0 <=
|
1101
|
+
# x/M <= 2.4, the absolute error in the result is bounded by 60 (and
|
1102
|
+
# is usually much smaller).
|
1103
|
+
def _iexp(x, m, l=8)
|
1104
|
+
|
1105
|
+
# Algorithm: to compute exp(z) for a real number z, first divide z
|
1106
|
+
# by a suitable power R of 2 so that |z/2**R| < 2**-L. Then
|
1107
|
+
# compute expm1(z/2**R) = exp(z/2**R) - 1 using the usual Taylor
|
1108
|
+
# series
|
1109
|
+
#
|
1110
|
+
# expm1(x) = x + x**2/2! + x**3/3! + ...
|
1111
|
+
#
|
1112
|
+
# Now use the identity
|
1113
|
+
#
|
1114
|
+
# expm1(2x) = expm1(x)*(expm1(x)+2)
|
1115
|
+
#
|
1116
|
+
# R times to compute the sequence expm1(z/2**R),
|
1117
|
+
# expm1(z/2**(R-1)), ... , exp(z/2), exp(z).
|
1118
|
+
|
1119
|
+
# Find R such that x/2**R/M <= 2**-L
|
1120
|
+
r = _nbits((x<<l)/m)
|
1121
|
+
|
1122
|
+
# Taylor series. (2**L)**T > M
|
1123
|
+
t = -(-10*_number_of_digits(m)/(3*l)).to_i
|
1124
|
+
y = _div_nearest(x, t)
|
1125
|
+
mshift = m<<r
|
1126
|
+
(1...t).to_a.reverse.each do |i|
|
1127
|
+
y = _div_nearest(x*(mshift + y), mshift * i)
|
1128
|
+
end
|
1129
|
+
|
1130
|
+
# Expansion
|
1131
|
+
(0...r).to_a.reverse.each do |k|
|
1132
|
+
mshift = m<<(k+2)
|
1133
|
+
y = _div_nearest(y*(y+mshift), mshift)
|
1134
|
+
end
|
1135
|
+
|
1136
|
+
return m+y
|
1137
|
+
end
|
1138
|
+
|
1139
|
+
# We'll memoize the digits of log(10):
|
1140
|
+
@log10_digits = "23025850929940456840179914546843642076011014886"
|
1141
|
+
class <<self
|
1142
|
+
attr_accessor :log10_digits
|
1143
|
+
end
|
1144
|
+
|
1145
|
+
# Given an integer p >= 0, return floor(10**p)*log(10).
|
1146
|
+
def _log10_digits(p)
|
1147
|
+
# digits are stored as a string, for quick conversion to
|
1148
|
+
# integer in the case that we've already computed enough
|
1149
|
+
# digits; the stored digits should always be correct
|
1150
|
+
# (truncated, not rounded to nearest).
|
1151
|
+
raise ArgumentError, "p should be nonnegative" if p<0
|
1152
|
+
if p >= AuxiliarFunctions.log10_digits.length
|
1153
|
+
digits = nil
|
1154
|
+
# compute p+3, p+6, p+9, ... digits; continue until at
|
1155
|
+
# least one of the extra digits is nonzero
|
1156
|
+
extra = 3
|
1157
|
+
loop do
|
1158
|
+
# compute p+extra digits, correct to within 1ulp
|
1159
|
+
m = 10**(p+extra+2)
|
1160
|
+
digits = _div_nearest(_ilog(10*m, m), 100).to_s
|
1161
|
+
break if digits[-extra..-1] != '0'*extra
|
1162
|
+
extra += 3
|
1163
|
+
end
|
1164
|
+
# keep all reliable digits so far; remove trailing zeros
|
1165
|
+
# and next nonzero digit
|
1166
|
+
AuxiliarFunctions.log10_digits = digits.sub(/0*$/,'')[0...-1]
|
1167
|
+
end
|
1168
|
+
return (AuxiliarFunctions.log10_digits[0...p+1]).to_i
|
1169
|
+
end
|
1170
|
+
|
1171
|
+
# Compute an approximation to exp(c*10**e), with p decimal places of
|
1172
|
+
# precision.
|
1173
|
+
#
|
1174
|
+
# Returns integers d, f such that:
|
1175
|
+
#
|
1176
|
+
# 10**(p-1) <= d <= 10**p, and
|
1177
|
+
# (d-1)*10**f < exp(c*10**e) < (d+1)*10**f
|
1178
|
+
#
|
1179
|
+
# In other words, d*10**f is an approximation to exp(c*10**e) with p
|
1180
|
+
# digits of precision, and with an error in d of at most 1. This is
|
1181
|
+
# almost, but not quite, the same as the error being < 1ulp: when d
|
1182
|
+
# = 10**(p-1) the error could be up to 10 ulp.
|
1183
|
+
def dexp(c, e, p)
|
1184
|
+
# we'll call iexp with M = 10**(p+2), giving p+3 digits of precision
|
1185
|
+
p += 2
|
1186
|
+
|
1187
|
+
# compute log(10) with extra precision = adjusted exponent of c*10**e
|
1188
|
+
extra = [0, e + _number_of_digits(c) - 1].max
|
1189
|
+
q = p + extra
|
1190
|
+
|
1191
|
+
# compute quotient c*10**e/(log(10)) = c*10**(e+q)/(log(10)*10**q),
|
1192
|
+
# rounding down
|
1193
|
+
shift = e+q
|
1194
|
+
if shift >= 0
|
1195
|
+
cshift = c*10**shift
|
1196
|
+
else
|
1197
|
+
cshift = c/10**-shift
|
1198
|
+
end
|
1199
|
+
quot, rem = cshift.divmod(_log10_digits(q))
|
1200
|
+
|
1201
|
+
# reduce remainder back to original precision
|
1202
|
+
rem = _div_nearest(rem, 10**extra)
|
1203
|
+
|
1204
|
+
# error in result of _iexp < 1s20; error after division < 0.62
|
1205
|
+
return _div_nearest(_iexp(rem, 10**p), 1000), quot - p + 3
|
1206
|
+
end
|
1207
|
+
|
1208
|
+
# number of bits in a nonnegative integer
|
1209
|
+
def _number_of_digits(i)
|
1210
|
+
raise TypeError, "The argument to _number_of_digits should be nonnegative." if i < 0
|
1211
|
+
if i.is_a?(Fixnum) || (i > NUMBER_OF_DIGITS_MAX_VALID_LOG)
|
1212
|
+
# for short integers this is faster
|
1213
|
+
# note that here we return 1 for 0
|
1214
|
+
i.to_s.length
|
1215
|
+
else
|
1216
|
+
(::Math.log10(i)+1).floor
|
1217
|
+
end
|
1218
|
+
end
|
1219
|
+
NUMBER_OF_DIGITS_MAX_VALID_LOG = 10**(Float::DIG-1)
|
1220
|
+
|
1221
|
+
end # AuxiliarFunctions
|
1222
|
+
|
1223
|
+
# This is for using auxiliar functions from DecNum instance method
|
1224
|
+
# without the "AuxiliarFunctions." prefix
|
1225
|
+
include AuxiliarFunctions
|
1226
|
+
# If we need to use them from DecNum class methods, we can avoid
|
1227
|
+
# the use of the prefix with:
|
1228
|
+
# extend AuxiliarFunctions
|
1229
|
+
|
1230
|
+
end
|
1231
|
+
|
1232
|
+
module_function
|
1233
|
+
# DecNum constructor. See DecNum#new for the parameters.
|
1234
|
+
# If a DecNum is passed a reference to it is returned (no new object is created).
|
1235
|
+
def DecNum(*args)
|
1236
|
+
DecNum.Num(*args)
|
1237
|
+
end
|
1238
|
+
|
1239
|
+
end # Flt
|