ruby-calc 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,6 @@
1
+ require "forwardable"
2
+
3
+ module Kernel
4
+ extend Forwardable
5
+ def_delegators Calc, *Calc::ALL_BUILTINS
6
+ end
@@ -0,0 +1,208 @@
1
+ module Calc
2
+ class Numeric
3
+ # Modulo operator
4
+ #
5
+ # x % y is equivalent to x.mod(y). Rounding mode is determined by
6
+ # Calc.config(:mod).
7
+ #
8
+ # @param y [Integer]
9
+ # @return [Calc::Numeric]
10
+ # @example
11
+ # Calc::Q(11).mod(5) #=> Calc::Q(1)
12
+ # Calc::C(11, 11).mod(5) #=> Calc::C(1+1i)
13
+ def %(other)
14
+ mod other
15
+ end
16
+
17
+ # Unary plus. Returns the receiver's value.
18
+ #
19
+ # @return [Calc::Numeric]
20
+ # @example
21
+ # +Calc::C(1,1) #=> Calc::C(1,1)
22
+ # +Calc::Q(1) #=> Calc::Q(1)
23
+ def +@
24
+ self
25
+ end
26
+
27
+ # Returns the square of the absolute value
28
+ #
29
+ # This method exists for compatibility with ruby Complex/Numeric.
30
+ #
31
+ # @return [Calc::C,Calc::Q]
32
+ # @example
33
+ # Calc::Q(5).abs2 #=> Calc::Q(25)
34
+ # Calc::C(3, -4).abs2 #=> Calc:c::Q(25)
35
+ def abs2
36
+ abs * abs
37
+ end
38
+
39
+ # Ceiling
40
+ #
41
+ # For real self, returns the least integer not less than self.
42
+ #
43
+ # For complex self, returns a complex number composed of the ceiling
44
+ # of the real and imaginary parts separately.
45
+ #
46
+ # @return [Calc::Q,Calc::C]
47
+ # @example
48
+ # Calc::Q(1.23).ceil #=> Calc::Q(2)
49
+ # Calc::C(7.8, 9.1).ceil #=> Calc::C(8+10i)
50
+ def ceil
51
+ appr(1, 1)
52
+ end
53
+
54
+ # Division
55
+ #
56
+ # This method exists for ruby compatibility. Note that Fixnum#fdiv will
57
+ # return a Float, however Q#div returns another Q.
58
+ #
59
+ # @param y [Numeric]
60
+ # @return [Calc::C,Calc::Q]
61
+ # @raise [Calc::MathError] if y is 0
62
+ # @example
63
+ # Calc::Q(2, 3).fdiv(0.5) #=> Calc::Q(~1.33333333333333333333)
64
+ # Calc::C(11, 22).fdiv(3) #=> Calc::C(~3.66666666666666666667+~7.33333333333333333333i)
65
+ def fdiv(y)
66
+ self / y
67
+ end
68
+
69
+ # Floor
70
+ #
71
+ # For real self, returns the greatest integer not greater than self.
72
+ #
73
+ # For complex self, returns a complex number composed of the floor of the
74
+ # real and imaginary parts separately.
75
+ #
76
+ # @return [Calc::Q,Calc::C]
77
+ # @example
78
+ # Calc::Q(1.23).floor #=> Calc::Q(1)
79
+ # Calc::C(7.8, 9.1).floor #=> Calc::C(7+9i)
80
+ def floor
81
+ appr(1, 0)
82
+ end
83
+
84
+ # Floor of logarithm to base 10
85
+ #
86
+ # Returns the greatest integer n for which 10^n <= self.
87
+ #
88
+ # @return [Calc::Q]
89
+ # @raise [Calc::MathError] if self is zero
90
+ # @example
91
+ # Calc::Q("1/15").ilog10 #=> Calc::Q(-2)
92
+ # Calc::Q(777).ilog10 #=> Calc::Q(2)
93
+ # Calc::C(10, 10).ilog10 #=> Calc::Q(1)
94
+ def ilog10
95
+ ilog 10
96
+ end
97
+
98
+ # Floor of logarithm to base 2
99
+ #
100
+ # Returns the greatest integer n for which 2^n <= self
101
+ #
102
+ # @return [Calc::Q]
103
+ # @raise [Calc::MathError] if self is zero
104
+ # @example
105
+ # Calc::Q("1/15").ilog2 #=> Calc::Q(-4)
106
+ # Calc::Q(777).ilog2 #=> Calc::Q(9)
107
+ # Calc::C(10, 10).ilog2 #=> Calc::Q(3)
108
+ def ilog2
109
+ ilog 2
110
+ end
111
+
112
+ # Returns 1 if self is an integer, otherwise 0.
113
+ #
114
+ # @return [Calc::Q]
115
+ # @example
116
+ # Calc::Q(1).isint #=> Calc::Q(1)
117
+ # Calc::Q(0.5).isint #=> Calc::Q(0)
118
+ def isint
119
+ int? ? Q::ONE : Q::ZERO
120
+ end
121
+
122
+ # Base 2 logarithm
123
+ #
124
+ # @return [Calc::Q]
125
+ # @example
126
+ # Calc::Q(1).log2 #=> Calc::Q(0)
127
+ # Calc::Q(2).log2 #=> Calc::Q(1)
128
+ # Calc::Q(10).log2 #=> Calc::Q(~3.32192809488736234786)
129
+ # Calc::Q(-2).log2 #=> Calc::C(1+~4.53236014182719380961i)
130
+ # Calc::C(1, 2).log2 #=> Calc::C(~1.16096404744368117393+~1.59727796468810880664i)
131
+ def log2(*args)
132
+ ln(*args) / Q::TWO.ln(*args)
133
+ end
134
+
135
+ # least-absol;ute-value residues modulo a specified number
136
+ #
137
+ # x.mmin(md) is equivalent to x.mod(md, 16)
138
+ #
139
+ # @param md [Numeric]
140
+ # @return [Calc::Numeric]
141
+ # @example
142
+ # Calc::Q(3).mmin(6) #=> Calc::Q(3)
143
+ # Calc::C(0, 3).mmin(6) #=> Calc::C(3i)
144
+ def mmin(md)
145
+ mod md, 16
146
+ end
147
+
148
+ # Returns true if the number is not zero. For complex `self`, this means
149
+ # that either the real or imaginary parts are not zero.
150
+ #
151
+ # @return [Boolean]
152
+ # @example
153
+ # Calc::Q(0).nonzero? #=> false
154
+ # Calc::Q(1).nonzero? #=> true
155
+ # Calc::C(0, 0).nonzero? #=> false
156
+ # Calc::C(1, 0).nonzero? #=> true
157
+ # Calc::C(0, 1).nonzero? #=> true
158
+ def nonzero?
159
+ !zero?
160
+ end
161
+
162
+ # Returns an array containing the absolute value and the argument (angle).
163
+ # This method exists for compatiblity with ruby's Numeric class.
164
+ #
165
+ # Note that: Calc.polar(a, b).polar == [a, b]
166
+ #
167
+ # @return [Array]
168
+ # @example
169
+ # Calc::Q(2).polar #=> [Calc::Q(2), Calc::Q(0)]
170
+ # Calc::C(1, 2).polar #=> [Calc::Q(2.23606797749978969641), Calc::Q(1.10714871779409050302)]
171
+ # Calc.polar(1, 2).polar #=> [Calc::Q(1), Calc::Q(2)]
172
+ def polar
173
+ [abs, arg]
174
+ end
175
+
176
+ # Rerurns an array containing the real and imaginary parts as elements.
177
+ # This method exists for compatibility with ruby's Numeric class.
178
+ #
179
+ # @return [Array]
180
+ # @example
181
+ # Calc::Q(2).rectangular #=> [Calc::Q(2), Calc::Q(0)]
182
+ # Calc::C(1, 2).rectangular #=> [Calc::Q(1), Calc::Q(2)]
183
+ def rectangular
184
+ [re, im]
185
+ end
186
+ alias rect rectangular
187
+
188
+ # Invokes the child class's `to_i` method to convert self to an integer.
189
+ #
190
+ # Note that the return value is a ruby Fixnum or Bignum. If you want to
191
+ # convert to an integer but have the result be a `Calc::Q` object, use
192
+ # `trunc` or `round`.
193
+ #
194
+ # @return [Fixnum,Bignum]
195
+ # @raise [RangeError] if self is complex with non-zero imaginary part
196
+ # @example
197
+ # Calc::Q("5/2").to_int #=> 2
198
+ # Calc::C(2, 0).to_int #=> 2
199
+ def to_int
200
+ to_i
201
+ end
202
+
203
+ # Provides support for Ruby type coercion.
204
+ def coerce(other)
205
+ [self.class.new(other), self]
206
+ end
207
+ end
208
+ end
@@ -0,0 +1,628 @@
1
+ module Calc
2
+ class Q
3
+ NEGONE = new(-1)
4
+ ZERO = new(0)
5
+ ONE = new(1)
6
+ TWO = new(2)
7
+
8
+ def **(other)
9
+ power(other)
10
+ end
11
+
12
+ # Inverse gudermannian function
13
+ #
14
+ # @param eps [Calc::Q] (optional) calculation accuracy
15
+ # @return [Calc::Q,Calc::C]
16
+ # @example
17
+ # Calc::Q(1).agd #=> Calc::Q(1.22619117088351707081)
18
+ # Calc::Q(2).agd #=> Calc::C(1.5234524435626735209-3.14159265358979323846i)
19
+ def agd(*args)
20
+ r = Calc::C(self).agd(*args)
21
+ r.real? ? r.re : r
22
+ end
23
+
24
+ # Returns the argument (the angle or phase) of a complex number in radians
25
+ #
26
+ # This method is used by non-complex classes, it will be 0 for positive
27
+ # values, pi() otherwise.
28
+ #
29
+ # @param eps [Calc::Q] (optional) calculation accuracy
30
+ # @return [Calc::Q]
31
+ # @example
32
+ # Calc::Q(-1).arg #=> Calc::Q(3.14159265358979323846)
33
+ # Calc::Q(1).arg #=> Calc::Q(0)
34
+ def arg(*args)
35
+ if self < 0
36
+ Calc.pi(*args)
37
+ else
38
+ ZERO
39
+ end
40
+ end
41
+ alias angle arg
42
+ alias phase arg
43
+
44
+ # Returns 1 if binary bit y is set in self, otherwise 0.
45
+ #
46
+ # @param y [Numeric] bit position
47
+ # @return [Calc::Q]
48
+ # @example
49
+ # Calc::Q(9).bit(0) #=> Calc::Q(1)
50
+ # Calc::Q(9).bit(1) #=> Calc::Q(0)
51
+ # @see bit?
52
+ def bit(y)
53
+ bit?(y) ? ONE : ZERO
54
+ end
55
+ alias [] bit
56
+
57
+ # Returns the number of bits in the integer part of `self`
58
+ #
59
+ # Note that this is compatible with ruby's Fixnum#bit_length. Libcalc
60
+ # provides a similar function called `highbit` with different semantics.
61
+ #
62
+ # This returns the bit position of the highest bit which is different to
63
+ # the sign bit. If there is no such bit (zero or -1), zero is returned.
64
+ #
65
+ # @return [Calc::Q]
66
+ # @example
67
+ # Calc::Q(0xff).bit_length #=> Calc::Q(8)
68
+ def bit_length
69
+ (negative? ? -self : self + ONE).log2.ceil
70
+ end
71
+
72
+ # Returns a string containing the character corresponding to a value
73
+ #
74
+ # Note that this is for compatibility with calc, normally in ruby you
75
+ # should just #chr
76
+ #
77
+ # @return [String]
78
+ # @example
79
+ # Calc::Q(88).char #=> "X"
80
+ def char
81
+ raise MathError, "Non-integer for char" unless int?
82
+ raise MathError, "Out of range for char" unless between?(0, 255)
83
+ if zero?
84
+ ""
85
+ else
86
+ to_i.chr
87
+ end
88
+ end
89
+
90
+ # Returns a string containing the character represented by `self` value
91
+ # according to encoding.
92
+ #
93
+ # Unlike the calc version (`char`), this allows numbers greater than 255
94
+ # if an encoding is specified.
95
+ #
96
+ # @return [String]
97
+ # @param encoding [Encoding]
98
+ # @example
99
+ # Calc::Q(88).chr #=> "X"
100
+ # Calc::Q(300).chr(Encoding::UTF_8) #=> Unicode I-breve
101
+ def chr(*args)
102
+ to_i.chr(*args)
103
+ end
104
+
105
+ # Complex conjugate
106
+ #
107
+ # As the conjugate of real x is x, this method returns self.
108
+ #
109
+ # @return [Calc::Q]
110
+ # @example
111
+ # Calc::Q(3).conj #=> 3
112
+ def conj
113
+ self
114
+ end
115
+ alias conjugate conj
116
+
117
+ # Ruby compatible integer division
118
+ #
119
+ # Calls `quo` to get the quotient of integer division, with rounding mode
120
+ # which specifies behaviour compatible with ruby's Numeric#div
121
+ #
122
+ # @param y [Numeric]
123
+ # @example
124
+ # Calc::Q(13).div(4) #=> Calc::Q(3)
125
+ # Calc::Q("11.5").div(4) #=> Calc::Q(2)
126
+ # @see Calc::Q#quo
127
+ def div(y)
128
+ quo(y, ZERO)
129
+ end
130
+
131
+ # Ruby compatible quotient/modulus
132
+ #
133
+ # Returns an array containing the quotient and modulus by dividing `self`
134
+ # by `y`. Rounding is compatible with the ruby method `Numeric#divmod`.
135
+ #
136
+ # Unlike `quomod`, this is not affected by `Calc.config(:quomod)`.
137
+ #
138
+ # @param y [Numeric]
139
+ # @example
140
+ # Calc::Q(11).divmod(3) #=> [Calc::Q(3), Calc::Q(2)]
141
+ # Calc::Q(11).divmod(-3) #=> [Calc::Q(-4), Calc::Q(-1)]
142
+ def divmod(y)
143
+ quomod(y, ZERO)
144
+ end
145
+
146
+ # Iterates the given block, yielding values from `self` decreasing by 1
147
+ # down to and including `limit`
148
+ #
149
+ # x.downto(limit) is equivalent to x.step(by: -1, to: limit)
150
+ #
151
+ # If no block is given, an Enumerator is returned instead.
152
+ #
153
+ # @return [Enumerator,nil]
154
+ # @param limit [Numeric] lowest value to return
155
+ # @example
156
+ # Calc::Q(10).downto(5) { |i| print i, " " } #=> 10 9 8 7 6 5
157
+ def downto(limit, &block)
158
+ step(limit, NEGONE, &block)
159
+ end
160
+
161
+ # Returns a string which if evaluated creates a new object with the original value
162
+ #
163
+ # @return [String]
164
+ # @example
165
+ # Calc::Q(0.5).estr #=> "Calc::Q(1,2)"
166
+ def estr
167
+ s = self.class.name
168
+ s << "("
169
+ s << (int? ? num.to_s : "#{ num },#{ den }")
170
+ s << ")"
171
+ s
172
+ end
173
+
174
+ # Returns an array; [gcd, lcm]
175
+ #
176
+ # This method exists for compatibility with ruby's Integer class, however
177
+ # note that the libcalc version works on rational numbers and the lcm can
178
+ # be negative. You can also pass more than one value.
179
+ #
180
+ # @return [Array]
181
+ # @example
182
+ # Calc::Q(2).gcdlcm(2) #=> [Calc::Q(2), Calc::Q(2)]
183
+ # Calc::Q(3).gcdlcm(-7) #=> [Calc::Q(1), Calc::Q(-21)]
184
+ def gcdlcm(*args)
185
+ [gcd(*args), lcm(*args)]
186
+ end
187
+
188
+ # Gudermannian function
189
+ #
190
+ # @param eps [Calc::Q] (optional) calculation accuracy
191
+ # @return [Calc::Q]
192
+ # @example
193
+ # Calc::Q(1).gd #=> Calc::Q(0.86576948323965862429)
194
+ def gd(*args)
195
+ r = Calc::C(self).gd(*args)
196
+ r.real? ? r.re : r
197
+ end
198
+
199
+ # Returns the corresponding imaginary number
200
+ #
201
+ # @return [Calc::C]
202
+ # @example
203
+ # Calc::Q(1).i #=> Calc::C(1i)
204
+ def i
205
+ Calc::C(ZERO, self)
206
+ end
207
+
208
+ def im
209
+ ZERO
210
+ end
211
+ alias imaginary im
212
+
213
+ # Returns true if the number is imaginary. Instances of this class always
214
+ # return false.
215
+ #
216
+ # @return [Boolean]
217
+ # @example
218
+ # Calc::Q(1).imag? #=> false
219
+ def imag?
220
+ false
221
+ end
222
+
223
+ def inspect
224
+ "Calc::Q(#{ self })"
225
+ end
226
+
227
+ def iseven
228
+ even? ? ONE : ZERO
229
+ end
230
+
231
+ # Returns 1 if the number is imaginary, otherwise returns 0. Instance of
232
+ # this class always return 0.
233
+ #
234
+ # @return [Calc::Q]
235
+ # @example
236
+ # Calc::Q(1).isimag #=> Calc::Q(0)
237
+ def isimag
238
+ ZERO
239
+ end
240
+
241
+ # Returns 1 if self exactly divides y, otherwise return 0.
242
+ #
243
+ # @return [Calc::Q]
244
+ # @example
245
+ # Calc::Q(6).ismult(2) #=> Calc::Q(1)
246
+ # Calc::Q(2).ismult(6) #=> Calc::Q(0)
247
+ # @see Calc::Q#mult?
248
+ def ismult(y)
249
+ mult?(y) ? ONE : ZERO
250
+ end
251
+
252
+ def isodd
253
+ odd? ? ONE : ZERO
254
+ end
255
+
256
+ # Returns 1 if self is prime, 0 if it is not prime. This function can't
257
+ # be used for odd numbers > 2^32.
258
+ #
259
+ # @return [Calc::Q]
260
+ # @raise [Calc::MathError] if self is odd and > 2^32
261
+ # @example
262
+ # Calc::Q(2**31 - 9).isprime #=> Calc::Q(0)
263
+ # Calc::Q(2**31 - 1).isprime #=> Calc::Q(1)
264
+ def isprime
265
+ prime? ? ONE : ZERO
266
+ end
267
+
268
+ # Returns 1 if this number has zero imaginary part, otherwise returns 0.
269
+ # Instances of this class always return 1.
270
+ #
271
+ # @return [Calc::Q]
272
+ # @example
273
+ # Calc::Q(1).isreal #=> Calc::Q(1)
274
+ def isreal
275
+ ONE
276
+ end
277
+
278
+ # Returns 1 if both values are relatively prime
279
+ #
280
+ # @param other [Integer]
281
+ # @return [Calc::Q]
282
+ # @raise [Calc::MathError] if either values are non-integers
283
+ # @example
284
+ # Calc::Q(6).isrel(5) #=> Calc::Q(1)
285
+ # Calc::Q(6).isrel(2) #=> Calc::Q(0)
286
+ # @see Calc::Q#rel?
287
+ def isrel(y)
288
+ rel?(y) ? ONE : ZERO
289
+ end
290
+
291
+ # Returns 1 if this value is a square
292
+ #
293
+ # @return [Calc::Q]
294
+ # @example
295
+ # Calc::Q(25).issq #=> Calc::Q(1)
296
+ # Calc::Q(3).issq #=> Calc::Q(0)
297
+ # Calc::Q("4/25").issq #=> Calc::Q(1)
298
+ # @see Calc::Q#sq?
299
+ def issq
300
+ sq? ? ONE : ZERO
301
+ end
302
+
303
+ # test for equaility modulo a specific number
304
+ #
305
+ # Returns 1 if self is congruent to y modulo md, otherwise 0.
306
+ #
307
+ # @param y [Numeric]
308
+ # @param md [Numeric]
309
+ # @return [Calc::Q]
310
+ # @example
311
+ # Calc::Q(5).meq(33, 7) #=> Calc::Q(1)
312
+ # Calc::Q(5).meq(32, 7) #=> Calc::Q(0)
313
+ # @see Calc::Q#meq?
314
+ def meq(y, md)
315
+ meq?(y, md) ? ONE : ZERO
316
+ end
317
+
318
+ # test for inequality modulo a specific number
319
+ #
320
+ # Reurns 1 if self is not congruent to y modulo md, otherwise 0.
321
+ # This is the opposite of #meq.
322
+ #
323
+ # @param y [Numeric]
324
+ # @param md [Numeric]
325
+ # @return [Calc::Q]
326
+ # @example
327
+ # Calc::Q(5).mne(33, 7) #=> Calc::Q(0)
328
+ # Calc::Q(5).mne(32, 7) #=> Calc::Q(1)
329
+ # @see Calc::Q#mne?
330
+ def mne(y, md)
331
+ meq?(y, md) ? ZERO : ONE
332
+ end
333
+
334
+ # test for inequality modulo a specific number
335
+ #
336
+ # Returns true of self is not congruent to y modulo md.
337
+ # This is the opposiute of #meq?.
338
+ #
339
+ # @param y [Numeric]
340
+ # @param md [Numeric]
341
+ # @return [Boolean]
342
+ # @example
343
+ # Calc::Q(5).mne?(33, 7) #=> false
344
+ # Calc::Q(5).mne?(32, 6) #=> true
345
+ def mne?(y, md)
346
+ !meq?(y, md)
347
+ end
348
+
349
+ # Ruby compatible modulus
350
+ #
351
+ # Returns the modulus of `self` divided by `y`.
352
+ #
353
+ # Rounding is compatible with the ruby method Numeric#modulo. Unlike
354
+ # `mod`, this is not affected by `Calc.confg(:mod)`.
355
+ #
356
+ # @param y [Numeric]
357
+ # @example
358
+ # Calc::Q(13).modulo(4) #=> Calc::Q(1)
359
+ # Calc::Q(13).modulo(-4) #=> Calc::Q(-3)
360
+ def modulo(y)
361
+ mod(y, ZERO)
362
+ end
363
+
364
+ # Return true if `self` is less than zero.
365
+ #
366
+ # This method exists for ruby Fixnum/Rational compatibility
367
+ #
368
+ # @return [Boolean]
369
+ # @example
370
+ # Calc::Q(-1).negative? #=> true
371
+ # Calc::Q(0).negative? #=> false
372
+ # Calc::Q(1).negative? #=> false
373
+ def negative?
374
+ self < ZERO
375
+ end
376
+
377
+ # Returns self.
378
+ #
379
+ # This method is for ruby Integer compatibility
380
+ #
381
+ # @return [Calc::Q]
382
+ def ord
383
+ self
384
+ end
385
+
386
+ # Return true if `self` is greater than zero.
387
+ #
388
+ # This method exists for ruby Fixnum/Rational compatibility
389
+ #
390
+ # @return [Boolean]
391
+ # @example
392
+ # Calc::Q(-1).positive? #=> false
393
+ # Calc::Q(0).positive? #=> false
394
+ # Calc::Q(1).positive? #=> true
395
+ def positive?
396
+ self > ZERO
397
+ end
398
+
399
+ # Returns one less than self.
400
+ #
401
+ # This method exists for ruby Fixnum/Integer compatibility.
402
+ #
403
+ # @return [Calc::Q]
404
+ # @example
405
+ # Calc::Q(1).pred #=> Calc::Q(0)
406
+ def pred
407
+ self - ONE
408
+ end
409
+
410
+ # Probabilistic primacy test
411
+ #
412
+ # Returns 1 if ptest? would have returned true, otherwise 0.
413
+ #
414
+ # @param count [Integer]
415
+ # @param skip [Integer]
416
+ # @return [Calc::Q]
417
+ # @see Calc::Q#ptest?
418
+ def ptest(*args)
419
+ ptest?(*args) ? ONE : ZERO
420
+ end
421
+
422
+ # Returns a simpler approximation of the value if the optional argument eps
423
+ # is given (rat-|eps| <= result <= rat+|eps|), self otherwise.
424
+ #
425
+ # Note that this method exists for ruby Numeric compatibility. Libcalc has
426
+ # an alternative approximation method with different semantics, see `appr`.
427
+ #
428
+ # @param eps [Float,Rational]
429
+ # @return [Calc::Q]
430
+ # @example
431
+ # Calc::Q(5033165, 16777216).rationalize #=> Calc::Q(5033165/16777216)
432
+ # Calc::Q(5033165, 16777216).rationalize(Rational('0.01')) #=> Calc::Q(3/10)
433
+ # Calc::Q(5033165, 16777216).rationalize(Rational('0.1')) #=> Calc::Q(1/3)
434
+ def rationalize(eps = nil)
435
+ eps ? Q.new(to_r.rationalize(eps)) : self
436
+ end
437
+
438
+ def re
439
+ self
440
+ end
441
+
442
+ # Returns true if this number has zero imaginary part. Instances of this
443
+ # class always return true.
444
+ #
445
+ # @return [Boolean]
446
+ # @example
447
+ # Calc::Q(1).real? #=> true
448
+ def real?
449
+ true
450
+ end
451
+
452
+ # Remainder of `self` divided by `y`
453
+ #
454
+ # This method is provided for compatibility with ruby's
455
+ # `Numeric#remainder`. Unlike `%` and `mod`, this method behaves the same
456
+ # as the ruby version, unaffected by `Calc.config(:mod).
457
+ #
458
+ # @param y [Numeric]
459
+ # @return [Calc::C,Calc::Q]
460
+ # @example
461
+ # Calc::Q(13).remainder(4) #=> Calc::Q(1)
462
+ def remainder(y)
463
+ z = modulo(y)
464
+ if !z.zero? && ((self < 0 && y > 0) || (self > 0 && y < 0))
465
+ z - y
466
+ else
467
+ z
468
+ end
469
+ end
470
+
471
+ # Invokes the given block with the sequence of numbers starting at self
472
+ # incrementing by step (default 1) on each call.
473
+ #
474
+ # In the first format, uses keyword parameters:
475
+ # x.step(by: step, to: limit)
476
+ #
477
+ # In the second format, uses positional parameters:
478
+ # x.step(limit = nil, step = 1)
479
+ #
480
+ # If step is negative, the sequence decrements instead of incrementing.
481
+ # If step is zero, the sequence will yield self forever.
482
+ #
483
+ # If limit exists, the sequence will stop once the next item yielded would
484
+ # be higher than limit (if step is positive) or lower than limit (if step
485
+ # is negative). If limit is nil, the sequence never stops.
486
+ #
487
+ # If no block is givem, an Enumerator is returned instead.
488
+ #
489
+ # This method was added for ruby Numeric compatibiliy; unlike Numeric#step,
490
+ # it is not an error for step to be zero in the positional format.
491
+ #
492
+ # @param by [Numeric] amount to add to sequence each iteration
493
+ # @param to [Numeric] end of sequence value
494
+ # @return [Enumerator,nil]
495
+ # @example
496
+ # Calc::Q(1).step(10, 3).to_a #=> [Calc::Q(1), Calc::Q(4), Calc::Q(7), Calc::Q(10)]
497
+ # Calc::Q(10).step(by: -2).take(4) #=> [Calc::Q(10), Calc::Q(8), Calc::Q(6), Calc::Q(4)]
498
+ # Calc::Q(1).exp.step(to: Calc.pi, by: "0.2") { |q| print q, " " } #=> nil
499
+ # prints:
500
+ # 2.71828182845904523536 2.91828182845904523536 3.11828182845904523536
501
+ def step(a1 = nil, a2 = ONE)
502
+ return to_enum(:step, a1, a2) unless block_given?
503
+ to, by = step_args(a1, a2)
504
+ loop { yield self } if by.zero?
505
+ i = self
506
+ loop do
507
+ break if to && ((by.positive? && i > to) || (by.negative? && i < to))
508
+ yield i
509
+ i += by
510
+ end
511
+ end
512
+
513
+ # work out what the caller meant with their args to #step
514
+ # returns an array of [to, by] parameters
515
+ def step_args(a1, a2)
516
+ if a1.is_a?(Hash)
517
+ # fake keywords style
518
+ badkeys = a1.keys - %i(to by)
519
+ raise ArgumentError, "Unknown keywords: #{ badkeys.join(", ") }" if badkeys.any?
520
+ to = a1.fetch(:to, nil)
521
+ by = a1.fetch(:by, ONE)
522
+ else
523
+ # positional style (limit, step)
524
+ to = a1
525
+ by = a2
526
+ end
527
+ [to ? Q.new(to) : nil, Q.new(by)]
528
+ end
529
+ private :step_args
530
+
531
+ # Returns one more than self.
532
+ #
533
+ # This method exists for ruby Fixnum/Integer compatibility.
534
+ #
535
+ # @return [Calc::Q]
536
+ # @example
537
+ # Calc::Q(1).pred #=> Calc::Q(2)
538
+ def succ
539
+ self + ONE
540
+ end
541
+ alias next succ
542
+
543
+ # Iterates the given block `self` times, passing in values from zero to
544
+ # self - 1
545
+ #
546
+ # If no block is given, an Enumerator is returned instead.
547
+ #
548
+ # @return [Enumerator,nil]
549
+ # @example
550
+ # Calc::Q(5).times { |i| print i, " " }
551
+ # #=> 0 1 2 3 4
552
+ def times
553
+ return to_enum(:times) unless block_given?
554
+ i = ZERO
555
+ while i < self
556
+ yield i
557
+ i += ONE
558
+ end
559
+ end
560
+
561
+ # Returns a ruby Complex number with self as the real part and zero
562
+ # imaginary part.
563
+ #
564
+ # @return [Complex]
565
+ # @example
566
+ # Calc::Q(2).to_c #=> (2+0i)
567
+ # Calc::Q(2.5).to_c #=> ((5/2)+0i)
568
+ def to_c
569
+ Complex(int? ? to_i : to_r, 0)
570
+ end
571
+
572
+ # Returns a Calc::C complex number with self as the real part and zero
573
+ # imaginary part.
574
+ #
575
+ # @return [Calc::C]
576
+ # @example
577
+ # Calc::Q(2).to_complex #=> Calc::C(2)
578
+ def to_complex
579
+ C.new(self, 0)
580
+ end
581
+
582
+ # libcalc has no concept of floating point numbers. so we use ruby's
583
+ # Rational#to_f
584
+ def to_f
585
+ to_r.to_f
586
+ end
587
+
588
+ # convert to a core ruby Rational
589
+ def to_r
590
+ Rational(numerator.to_i, denominator.to_i)
591
+ end
592
+
593
+ alias truncate trunc
594
+
595
+ # Iterates the given block, yielding values from `self` increasing by 1
596
+ # up to and including `limit`
597
+ #
598
+ # x.upto(limit) is equivalent to x.step(by: 1, to: limit)
599
+ #
600
+ # If no block is given, an Enumerator is returned instead.
601
+ #
602
+ # @return [Enumerator,nil]
603
+ # @param limit [Numeric] highest value to return
604
+ # @example
605
+ # Calc::Q(5).upto(10) { |i| print i, " " } #=> 5 6 7 8 9 10
606
+ def upto(limit, &block)
607
+ step(limit, ONE, &block)
608
+ end
609
+
610
+ # Bitwise exclusive or of a set of integers
611
+ #
612
+ # xor(a, b, c, ...) is equivalent to (((a ^ b) ^ c) ... )
613
+ # note that ^ is the ruby xor operator, not the calc power operator.
614
+ #
615
+ # @return [Calc::Q]
616
+ # @example
617
+ # Calc::Q(3).xor(5) #=> Calc::Q(6)
618
+ # Calc::Q(5).xor(3, -7, 2, 9) #=> Calc::Q(-12)
619
+ def xor(*args)
620
+ args.inject(self, :^)
621
+ end
622
+
623
+ # aliases for compatibility with ruby Fixnum/Bignum/Rational
624
+ alias imag im
625
+ alias integer? int?
626
+ alias real re
627
+ end
628
+ end