ruby-calc 0.1.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.
- 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
|