ruby-calc 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +15 -0
- data/.rubocop.yml +52 -0
- data/.rubocop_todo.yml +11 -0
- data/.travis.yml +15 -0
- data/.yardopts +1 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +497 -0
- data/Rakefile +23 -0
- data/bin/console +10 -0
- data/bin/install_calc.sh +18 -0
- data/bin/makefile.patch +48 -0
- data/bin/setup +7 -0
- data/bin/todo.rb +374 -0
- data/ext/calc/c.c +775 -0
- data/ext/calc/calc.c +192 -0
- data/ext/calc/calc.h +71 -0
- data/ext/calc/config.c +239 -0
- data/ext/calc/convert.c +193 -0
- data/ext/calc/extconf.rb +29 -0
- data/ext/calc/math_error.c +72 -0
- data/ext/calc/numeric.c +623 -0
- data/ext/calc/q.c +2755 -0
- data/lib/calc.rb +214 -0
- data/lib/calc/c.rb +371 -0
- data/lib/calc/import.rb +6 -0
- data/lib/calc/numeric.rb +208 -0
- data/lib/calc/q.rb +628 -0
- data/lib/calc/version.rb +3 -0
- data/ruby-calc.gemspec +29 -0
- metadata +167 -0
data/lib/calc/import.rb
ADDED
data/lib/calc/numeric.rb
ADDED
@@ -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
|
data/lib/calc/q.rb
ADDED
@@ -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
|