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
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 60dc0a56479aabb76308bf50c684b33dee34295a
|
4
|
+
data.tar.gz: 146f1c057188c53d530776232b992bc6f8de0042
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 138bc132c80fb43568cce386271ac3f8f9a331a80a861bc155e88b10e11bdf697bfd03becf96598a433d09b50be67519c4c93d0bac96608abab5aa0c223790b7
|
7
|
+
data.tar.gz: 33f6b72f5db4aeba9cd01b045b30eee2d904226111709cf20c7cb8b120be9900d2518bf0f65b3da1395ff48222e57bb78471f937cb9f5421fdbc8e3d2880d219
|
data/.gitignore
ADDED
data/.rubocop.yml
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
inherit_from: .rubocop_todo.yml
|
2
|
+
|
3
|
+
AllCops:
|
4
|
+
TargetRubyVersion: 2.0
|
5
|
+
|
6
|
+
# module/class docs are in the c extension
|
7
|
+
Style/Documentation:
|
8
|
+
Enabled: false
|
9
|
+
|
10
|
+
Style/FirstArrayElementLineBreak:
|
11
|
+
Enabled: true
|
12
|
+
|
13
|
+
Style/SpaceInsideStringInterpolation:
|
14
|
+
EnforcedStyle: space
|
15
|
+
|
16
|
+
Style/StringLiterals:
|
17
|
+
EnforcedStyle: double_quotes
|
18
|
+
|
19
|
+
Style/StringLiteralsInInterpolation:
|
20
|
+
EnforcedStyle: double_quotes
|
21
|
+
|
22
|
+
# long modules / classes are OK here
|
23
|
+
Metrics/ClassLength:
|
24
|
+
Enabled: false
|
25
|
+
|
26
|
+
Metrics/ModuleLength:
|
27
|
+
Enabled: false
|
28
|
+
|
29
|
+
Metrics/LineLength:
|
30
|
+
Max: 100
|
31
|
+
|
32
|
+
# increase default complexity metrics
|
33
|
+
Metrics/CyclomaticComplexity:
|
34
|
+
Max: 8
|
35
|
+
|
36
|
+
Metrics/PerceivedComplexity:
|
37
|
+
Max: 8
|
38
|
+
|
39
|
+
Style/GlobalVars:
|
40
|
+
Exclude: [ "ext/**/extconf.rb" ]
|
41
|
+
|
42
|
+
Style/NumericLiterals:
|
43
|
+
Exclude: [ "test/*.rb" ]
|
44
|
+
|
45
|
+
Style/ClassAndModuleChildren:
|
46
|
+
Exclude: [ "test/*.rb" ]
|
47
|
+
|
48
|
+
Metrics/AbcSize:
|
49
|
+
Exclude: [ "test/*.rb" ]
|
50
|
+
|
51
|
+
Metrics/MethodLength:
|
52
|
+
Exclude: [ "test/*.rb" ]
|
data/.rubocop_todo.yml
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
# This configuration was generated by
|
2
|
+
# `rubocop --auto-gen-config`
|
3
|
+
# on 2016-05-14 09:35:37 +0930 using RuboCop version 0.40.0.
|
4
|
+
# The point is for the user to remove these configuration records
|
5
|
+
# one by one as the offenses are removed from the code base.
|
6
|
+
# Note that changes in the inspected code, or installation of new
|
7
|
+
# versions of RuboCop, may require this file to be generated again.
|
8
|
+
|
9
|
+
# Offense count: 2
|
10
|
+
Metrics/AbcSize:
|
11
|
+
Max: 24
|
data/.travis.yml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
sudo: required
|
2
|
+
language: ruby
|
3
|
+
rvm:
|
4
|
+
- 2.0
|
5
|
+
- 2.1
|
6
|
+
- 2.2
|
7
|
+
- 2.3.0
|
8
|
+
env:
|
9
|
+
- CALC_VERSION=2.12.5.0 # latest stable (12-Oct-2014)
|
10
|
+
- CALC_VERSION=2.12.5.4 # latest unstable (22-Feb-2016)
|
11
|
+
before_install:
|
12
|
+
- gem install bundler # travis ruby 2.0.0 installs bundler 1.7, update it
|
13
|
+
- bin/install_calc.sh
|
14
|
+
after_success:
|
15
|
+
- bin/todo.rb
|
data/.yardopts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
ext/**/*.c lib/**/*.rb
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2015 Tim Peters
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,497 @@
|
|
1
|
+
# ruby-calc [![Build Status](https://travis-ci.org/timpeters/ruby-calc.svg?branch=master)](https://travis-ci.org/timpeters/ruby-calc)
|
2
|
+
|
3
|
+
ruby-calc provides ruby bindings for calc, a c-style arbitrary precision calculator.
|
4
|
+
|
5
|
+
For information about calc, see: http://www.isthe.com/chongo/tech/comp/calc/index.html
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Calc must be installed.
|
10
|
+
|
11
|
+
OS | Instructions
|
12
|
+
--- | ------------
|
13
|
+
Fedora | `sudo yum install calc calc-libs calc-devel`
|
14
|
+
OS X | Install [Homebrew](http://brew.sh), then `brew install calc`
|
15
|
+
Debian/Ubuntu | Calc is packaged as "apcalc", but because it doesn't include a shared library it won't work, so see instructions under "Manual"
|
16
|
+
Manual | Download and install calc yourself by referring to the calc website, or using `bin/install_calc` from this repository
|
17
|
+
|
18
|
+
Add this line to your application's Gemfile:
|
19
|
+
|
20
|
+
```ruby
|
21
|
+
gem 'ruby-calc', git: 'git://github.com/timpeters/ruby-calc.git'
|
22
|
+
```
|
23
|
+
|
24
|
+
And then execute:
|
25
|
+
|
26
|
+
$ bundle
|
27
|
+
|
28
|
+
Or install it yourself as:
|
29
|
+
|
30
|
+
$ gem install ruby-calc
|
31
|
+
|
32
|
+
## Usage
|
33
|
+
|
34
|
+
The library provides 2 types of number classes:
|
35
|
+
|
36
|
+
### Rational Numbers (Calc::Q)
|
37
|
+
|
38
|
+
Rational numbers are a pair of integers (numerator and denominator). Each value can be arbitraily large; the number is always stored in lowest common terms with the sign in the numerator.
|
39
|
+
|
40
|
+
```ruby
|
41
|
+
# any numeric type can be passed as a parameter
|
42
|
+
Calc::Q(42) #=> Calc::Q(42)
|
43
|
+
Calc::Q(Rational(3,10)) #=> Calc::Q(0.3)
|
44
|
+
Calc::Q(Calc::Q(42)) #=> Calc::Q(42)
|
45
|
+
Calc::Q(0.3) #=> Calc::Q(~0.29999999999999998890)
|
46
|
+
|
47
|
+
# strings are parsed by the calc library, which allows real, rational
|
48
|
+
# exponential, scientific, hex, octal and binary:
|
49
|
+
Calc::Q("0.3") #=> Calc::Q("0.3") (compare to Float example above)
|
50
|
+
Calc::Q("3/10") #=> Calc::Q("0.3")
|
51
|
+
Calc::Q("1e10") #=> Calc::Q(10000000000)
|
52
|
+
Calc::Q("1e-10") #=> Calc::Q(0.0000000001)
|
53
|
+
Calc::Q("0x2a") #=> Calc::Q(42)
|
54
|
+
Calc::Q("052") #=> Calc::Q(42)
|
55
|
+
Calc::Q("0b101010") #=> Calc::Q(42)
|
56
|
+
|
57
|
+
# If you pass a second parameter, the first will be divided by it (if you
|
58
|
+
# are passing integers, you are effectively passing a numerator/denominator).
|
59
|
+
Calc::Q(1,4) #=> Calc::Q(0.25)
|
60
|
+
|
61
|
+
# rational arithmetic. you can provide ruby numbers or other calc classes as
|
62
|
+
# arguments to most operators
|
63
|
+
q1 = Calc::Q(42)
|
64
|
+
q2 = Calc::Q(13,4)
|
65
|
+
q1 + q2 #=> Calc::Q(45.25)
|
66
|
+
q1 - q2 #=> Calc::Q(38.75)
|
67
|
+
q1 * q2 #=> Calc::Q(136.5)
|
68
|
+
q1 / q2 #=> Calc::Q(~12.92307692307692307692)
|
69
|
+
|
70
|
+
# raise to power
|
71
|
+
q1 ** q2 #=> Calc::Q(188608.03646237737943757212)
|
72
|
+
```
|
73
|
+
|
74
|
+
### Complex numbers (Calc::C)
|
75
|
+
|
76
|
+
```ruby
|
77
|
+
# Complex numbers can be created by passing a real and imaginary pair of
|
78
|
+
# rational numbers. In this form, the arguments can be anything accepted by
|
79
|
+
# Calc::Q#new:
|
80
|
+
c1 = Calc::C(2, 3) #=> Calc::C(2+3i)
|
81
|
+
|
82
|
+
# You can pass a single Complex or Calc::C parameter:
|
83
|
+
c2 = Calc::C(Complex(-1,-1)) #=> Calc::C(-1-1i)
|
84
|
+
# note that ruby 2.1 and later allow complex literals which turn into Complex
|
85
|
+
# objects, so:
|
86
|
+
Calc::C(4+5i) #=> Calc::C(4+5i)
|
87
|
+
|
88
|
+
# You can also use the polar method to initialize a complex number by giving
|
89
|
+
# a modulus (radius) and argument (angle, in radians)
|
90
|
+
Calc.polar(1,2) #=> Calc::C(-0.416146836547142387+0.9092974268256816954i)
|
91
|
+
Calc.polar(c2.abs, c2.arg) #=> Calc::C(-1-1i)
|
92
|
+
# Polar will return a rational number if the result is not complex
|
93
|
+
Calc.polar(1, Calc.pi) #=> Calc::Q(-1)
|
94
|
+
|
95
|
+
# If any other single numeric type is passed, it is used as the real part and
|
96
|
+
# the imaginary part is set to zero:
|
97
|
+
c3 = Calc::C(1) #=> Calc::C(1)
|
98
|
+
|
99
|
+
# Complex arithmetic is available:
|
100
|
+
c1 + c2 #=> Calc::C(1+2i)
|
101
|
+
c1 - c2 #=> Calc::C(3+4i)
|
102
|
+
c1 * c2 #=> Calc::C(1-5i)
|
103
|
+
c1 / c2 #=> Calc::C(-2.5+0.5i)
|
104
|
+
c1 ** c2 #=> Calc::C(-0.47426003871893157744-0.56942019125139104294i)
|
105
|
+
|
106
|
+
# The real and imaginary parts can be retrieved with #re/#im
|
107
|
+
# (aliases #real/#imag). Calc::Q rational numbers are returned
|
108
|
+
(c1 / c2).re #=> Calc::Q(-2.5)
|
109
|
+
(c1 / c2).im #=> Calc::Q(-0.5)
|
110
|
+
```
|
111
|
+
|
112
|
+
### Built in functions
|
113
|
+
|
114
|
+
Where possible, calc builtin functions are exposed by this library are implemented as methods with the same name:
|
115
|
+
|
116
|
+
Method | Arguments | Description
|
117
|
+
------ | --------- | -----------
|
118
|
+
abs | x [, b] | absolute value of x (for complex x, within accuracy b)
|
119
|
+
acos | x [, b] | arccosine of x within accuracy b
|
120
|
+
acosh | x [, b] | hyperbolic arccosine of x within accuracy b
|
121
|
+
acot | x [, b] | inverse cotangent of x within accuracy b
|
122
|
+
acoth | x [, b] | inverse hyperbolic cotangent of x within accuracy b
|
123
|
+
acsc | x [, b] | inverse cosecant of x within accuracy b
|
124
|
+
acsch | x [, b] | inverse hyperbolic cosecant of x within accuracy b
|
125
|
+
agd | z [, b] | inverse gudermannian function of z within accuracy b
|
126
|
+
appr | x [, e, r] | approximate x as a multiple of e with rounding r
|
127
|
+
arg | x [, b] | argument (angle) of complex number x within acccuracy b
|
128
|
+
asec | x [, b] | inverse secant of x within accuracy b
|
129
|
+
asech | x [, b] | inverse hyperbolic secant of x within accuracy b
|
130
|
+
asin | x [, b] | arcsine of x within accuracy b
|
131
|
+
asinh | x [, b] | hyperbolic arcsine of x within accuracy b
|
132
|
+
atan | x [, b] | arctangent of x within accuracy b
|
133
|
+
atan2 | y, x [, b] | angle determined by the point (x,y) within accuracy b
|
134
|
+
atanh | x [, b] | hyperbolic arctangent of x within accuracy b
|
135
|
+
avg | x, y, ... | arithmetic mean of values
|
136
|
+
bernoulli | x | xth bernoulli number
|
137
|
+
bit | x, y | whether bit y in value x is set (also: #bit?)
|
138
|
+
bround | x [, p, r] | round x to p binary places with rounding r
|
139
|
+
btrunc | x [, p] | truncate x to p binary places
|
140
|
+
catalan| x | Catalan number for index x
|
141
|
+
cbrt | x [, b] | cube root of x within accuracy b
|
142
|
+
ceil | x | smallest integer greater than or equal to x
|
143
|
+
cfappr | x [, ...] | approximate x within accuracy e using continued fractions
|
144
|
+
cfsim | x [, r] | simplify x using continued fractions
|
145
|
+
char | x | character corresponding to integer x
|
146
|
+
cmp | x, y | compare values returning -1, 0 or 1 real or complex
|
147
|
+
comb | x, y | combinatorial number a!/b!(a-b)!
|
148
|
+
conj | x | complex conjugate of x
|
149
|
+
cos | x [, b] | cosine of x within accuracy b
|
150
|
+
cosh | x [, b] | hyperbolic cosine of x within accuracy b
|
151
|
+
cot | x [, b] | cotangent of x within accuracy b
|
152
|
+
coth | x [, b] | hyperbolic cotangent of x within accuracy b
|
153
|
+
csc | x [, b] | cosecant of x within accuracy b
|
154
|
+
csch | x [, b] | hyperbolic cosecant of x within accuracy b
|
155
|
+
den | x | denominator of x
|
156
|
+
digit | x, n [, b] | nth digit of x in base b
|
157
|
+
digits | x [, b] | number of intgral digits of x in base b
|
158
|
+
estr | x | text representation of a value
|
159
|
+
euler | n | nth euler number
|
160
|
+
exp | x [, b] | exponential function of x within accuracy b
|
161
|
+
fact | x | factorial of integer x
|
162
|
+
factor | x [, limit]| smallest prime factor of x not exceeding limit
|
163
|
+
fcnt | x, y | count number of times y divides x
|
164
|
+
frac | x | fractional part of x
|
165
|
+
frem | x, y | remove occurances of factor y from x
|
166
|
+
fib | z | zth Fibonacci number
|
167
|
+
freebernoulli | | free memory storing calculated bernoulli numbers
|
168
|
+
freeeuler | | free memory storing calculated euler numbers
|
169
|
+
floor | x | greatest integer less than or equal to x
|
170
|
+
gcd | x [, ...] | greatest common divisor
|
171
|
+
gcdrem | x, y | x divided repeatedly by gcd with b
|
172
|
+
gd | z [, b] | gudermannian function of z within accuracy b
|
173
|
+
highbit| x | high bit number in base 2 representation
|
174
|
+
hmean | x, y, ... | harmonic mean
|
175
|
+
hnrmod | v, h, n, r | computes v % (h * 2^n + r)
|
176
|
+
ilog | x, b | floor of logarithm to base b
|
177
|
+
ilog10 | x | floor of logarithm to base 10
|
178
|
+
ilog2 | x | floor of logarithm to base 2
|
179
|
+
int | x | integer part of x
|
180
|
+
inverse| x | inverse of x
|
181
|
+
iroot | x, n | integer nth root of x
|
182
|
+
iseven | x | whether a value is even (also: #even?)
|
183
|
+
isimag | x | whether a value is imaginary (also: #imag?)
|
184
|
+
isint | x | whether a value is an integer (also: #int?)
|
185
|
+
ismult | x, y | whether a x exactly divides y (also: #mult?)
|
186
|
+
isodd | x | whether a value is odd (also: #odd?)
|
187
|
+
isprime| x | tests if x is a small (< 2^32) prime (also: #prime?)
|
188
|
+
isqrt | x | integer part of square root of x
|
189
|
+
isreal | x | whether a value is real (also: #real?)
|
190
|
+
isrel | x, y | tests if x and y are relatively prime
|
191
|
+
issq | x | test if x is a square
|
192
|
+
jacobi | x, y | Jacobi symbol function
|
193
|
+
lcm | x [, ...] | least common multiple
|
194
|
+
lcmfact| x | lcm of positive integers up to x
|
195
|
+
lfactor| n, m | lowest prime factor of n in first m primes
|
196
|
+
ln | x [, b] | natural logarithm of x within accuracy b
|
197
|
+
log | x [, b] | base 10 logarithm of x within accuracy b
|
198
|
+
lowbit | x | low bit number in base 2 representation
|
199
|
+
ltol | x [, b] | leg-to-leg of unit right triangle within accuracy b
|
200
|
+
max | x [, ...] | maximum of values
|
201
|
+
meq | x, y, m | test for equality of x and y modulo m (also: #meq?)
|
202
|
+
min | x [, ...] | minimum of values
|
203
|
+
minv | x, m | inverse of x modulo m
|
204
|
+
mmin | x, y | x mod y value with smallest abs value
|
205
|
+
mne | x, y, m | test for inequality of x and y module m (also: #mne?)
|
206
|
+
mod | x, y [, r] | x modulo y with rounding r
|
207
|
+
near | x, y [, b] | nearness test (sign of (abs(x-y) - b)
|
208
|
+
nextcand| x [, ...] | next candidate prime
|
209
|
+
nextprime| x | next small prime after x
|
210
|
+
norm | x | norm (square of absolute value)
|
211
|
+
num | x | numerator of x
|
212
|
+
perm | x, y | permutation number x!/(x-y)!
|
213
|
+
pi | [b] | value of π within accuracy b
|
214
|
+
pix | x | number of primes not exceeding x
|
215
|
+
pfact | x | produt of primes up to x
|
216
|
+
places | x [, b] | number of places in fractional part in base b
|
217
|
+
pmod | x, y, m | mod of a power (x ^ y (mod m))
|
218
|
+
polar | r, t [, b] | complex number using polar coordinates
|
219
|
+
poly | ... | evaluate a polynomial given coefficients or coefficient list
|
220
|
+
popcnt | x [, b] | number of bits in x that match b (or 1)
|
221
|
+
power | x, y [, b] | x raised to the power of y within accuracy b
|
222
|
+
prevcand| x [, ...] | previous candidate prime
|
223
|
+
prevprime| x | previous small prime before x
|
224
|
+
ptest | n, [, c [, s] | probabilistic test of primality (also: #ptest?)
|
225
|
+
quo | x, y [, r] | integer quotient of a by b with rounding r
|
226
|
+
quomod | x, y | quotient and remainder of x divided by y
|
227
|
+
root | x, n [, b] | nth root of x within accuracy b
|
228
|
+
round | x [, p, r] | round x to p decimal places with rounding r
|
229
|
+
scale | x, y | scale value up or down by a power of two
|
230
|
+
sec | x [, b] | secant of x within accuracy b
|
231
|
+
sech | x [, b] | hyperbolic secant within accuracy b
|
232
|
+
sgn | x | sign of x (-1, 0, 1)
|
233
|
+
sin | x [, b] | sine of x within accuracy b
|
234
|
+
sinh | x [, b] | hyperbolic sine of x within accuracy b
|
235
|
+
sqrt | x [, b, z] | square root of x within accuracy b with rounding/sign controlled by z
|
236
|
+
ssq | ... | sum of squares of values
|
237
|
+
sum | ... | sum of values
|
238
|
+
tan | x [, b] | tangent of x within accuracy b
|
239
|
+
tanh | x [, b] | hyperbolic tangent of x within accuracy b
|
240
|
+
trunc | x [, p] | truncate x to p decimal places
|
241
|
+
version| | version of calc that ruby-calc was compiled with
|
242
|
+
|
243
|
+
Builtins with at least one required parameter are implemented as class methods of Calc::Q, Calc::C (or both) to allow object orientated style. Their behaviour matches the calc builtins as closely as possible. The receiver of these methods is what would have been the first parameter in calc.
|
244
|
+
|
245
|
+
```ruby
|
246
|
+
Calc::Q(1).sin #=> Calc::Q(0.84147098480789650665)
|
247
|
+
Calc::Q(2).power(3) #=> Calc::Q(8)
|
248
|
+
```
|
249
|
+
|
250
|
+
If you prefer the C-like style of calc, these are also available as class methods on Calc. This allows you to include Calc and use the builtins directly. These will call the rational/complex version of the method based on the type of the first parameter.
|
251
|
+
|
252
|
+
```ruby
|
253
|
+
Calc.sin(1) #=> Calc::Q(0.84147098480789650665)
|
254
|
+
Calc.power(2,3) #=> Calc::Q(8)
|
255
|
+
```
|
256
|
+
|
257
|
+
Functions with no arguments (other than precision/rounding modes) are only available as class methods:
|
258
|
+
|
259
|
+
```ruby
|
260
|
+
Calc.pi #=> Calc::Q(3.14159265358979323846)
|
261
|
+
```
|
262
|
+
|
263
|
+
### Trancendental functions
|
264
|
+
|
265
|
+
Transcendental functions such as sin, cos and pi, cannot be evaluated exactly as fractions. The result will be a rational number within a specific accuracy of the correct value (usually an absolute difference).
|
266
|
+
|
267
|
+
These methods have equivalent module versions for convenience. In the module version, the first parameter is equivalent to the receiver in the instance version. Example:
|
268
|
+
|
269
|
+
```ruby
|
270
|
+
# single parameter functions
|
271
|
+
Calc::Q(1).sin #=> Calc::Q(0.84147098480789650665)
|
272
|
+
Calc.sin(1) #=> Calc::Q(0.84147098480789650665)
|
273
|
+
|
274
|
+
# two parameter functions
|
275
|
+
Calc::Q(9).root(2) #=> Calc::Q(3)
|
276
|
+
Calc.root(9,2) #=> Calc::Q(3)
|
277
|
+
|
278
|
+
# functions with no parameters are only available as a module method
|
279
|
+
Calc.pi #=> Calc::Q(3.14159265358979323846)
|
280
|
+
```
|
281
|
+
|
282
|
+
The accuracy of transcendental functions will be within a specified `epsilon`. Each method has an optional extra parameter which provides this for a single call. If omitted a global epsilon is used (defaults to 1e-20). Epsilon must be greater than 0.
|
283
|
+
|
284
|
+
```ruby
|
285
|
+
# pi to default 20 decimal places:
|
286
|
+
Calc.pi #=> Calc::Q(3.14159265358979323846)
|
287
|
+
|
288
|
+
# pi to 2 decimal places:
|
289
|
+
Calc.pi("0.01") #=> Calc::Q(3.14)
|
290
|
+
|
291
|
+
# Avoid using a ruby float as a precision, since it won't exactly represent
|
292
|
+
# what you expect (see below in "Differences from Calc").
|
293
|
+
# For this reason it is recommended to use a Calc::Q or a string as the
|
294
|
+
# epsilon. Eg, pi to 400 decimal places:
|
295
|
+
Calc.pi("1e-400") #=> (long fraction omitted)
|
296
|
+
```
|
297
|
+
|
298
|
+
The default epsilon can be changed via the Calc.config method and will affect all subsequent method calls:
|
299
|
+
|
300
|
+
```ruby
|
301
|
+
Calc.config(:epsilon) #=> Calc::Q(0.00000000000000000001)
|
302
|
+
Calc.pi #=> Calc::Q(3.14159265358979323846)
|
303
|
+
Calc.config(:epsilon, "0.0001")
|
304
|
+
Calc.pi #=> Calc::Q(3.1416)
|
305
|
+
```
|
306
|
+
|
307
|
+
### Converting between numeric types
|
308
|
+
|
309
|
+
The following methods can be used to convert a ruby-calc class to ruby numeric types.
|
310
|
+
|
311
|
+
Method | Result
|
312
|
+
------ | ------
|
313
|
+
Calc::Q#to_f | Converts to ruby Float (precision can be lost!)
|
314
|
+
Calc::Q#to_i | Converts to ruby Fixnum/Bignum (discards remainder)
|
315
|
+
Calc::Q#to_r | Converts to ruby Rational
|
316
|
+
Calc::Q#to_c | Converts to ruby Complex
|
317
|
+
Calc::Q#to_complex | Converts to a Calc::C with zero imaginary part
|
318
|
+
Calc::C#to_c | Converts to ruby Complex
|
319
|
+
Calc::C#to_f | Converts to ruby Float, error if imaginary part is non-zero
|
320
|
+
Calc::C#to_i | Converts to ruby Fixnum/Bignum, error if imaginary part is non-zero
|
321
|
+
Calc::C#to_r | Converts to ruby Rational, error if imaginary part is non-zero
|
322
|
+
|
323
|
+
#### Converting to strings
|
324
|
+
|
325
|
+
Internally, `Calc::Q` are always stored as a rational number (fraction). Libcalc supports various output modes. The default is "real" which will output in decimal format.
|
326
|
+
|
327
|
+
```ruby
|
328
|
+
Calc.exp(1).to_s #=> "2.71828182845904523536"
|
329
|
+
```
|
330
|
+
|
331
|
+
Numbers are rounded after `Calc::Config.display` digits; if any rounding has to occur, a leading tilde is included in the output. If you don't want rounding, you can output as a fraction:
|
332
|
+
|
333
|
+
```ruby
|
334
|
+
Calc::Q(1,11).to_s #=> "~0.09090909090909090909"
|
335
|
+
Calc::Q(1,11).to_s(:frac) #=> "1/11"
|
336
|
+
```
|
337
|
+
|
338
|
+
`to_s` takes an optional parameter which is the output mode to use. It must be a symbol or a string with one of the following values:
|
339
|
+
|
340
|
+
```ruby
|
341
|
+
Calc::Q(1,20).to_s(:frac) #=> "1/20" base 10 fractions
|
342
|
+
Calc::Q(1,20).to_s(:int) #=> "~0" base 10 integers
|
343
|
+
Calc::Q(1,20).to_s(:real) #=> "0.05" base 10 floating point (default)
|
344
|
+
Calc::Q(1,20).to_s(:sci) #=> "5e-2" base 10 scientific notation
|
345
|
+
Calc::Q(1,20).to_s(:hex) #=> "1/0x14" base 16 fractions
|
346
|
+
Calc::Q(1,20).to_s(:oct) #=> "1/024" base 8 fractions
|
347
|
+
Calc::Q(1,20).to_s(:bin) #=> "1/0b10100 base 2 fractions
|
348
|
+
```
|
349
|
+
|
350
|
+
The default output mode can be set with [Calc::Config]. The output of `inspect` will match whatever the current default is.
|
351
|
+
|
352
|
+
Note that you can also provide `Calc::Q` objects to the ruby printf method. The format string parameter will coerce the number to the right internal type first (eg %d will display as an integer, %f as a floating point number). The display may have lost precision in this conversion.
|
353
|
+
|
354
|
+
### Configuration
|
355
|
+
|
356
|
+
Default output modes, precision, rounding modes, etc can be set with the `Calc.config` method. It acts the same as the `config()` function in calc:
|
357
|
+
* The first parameter is the name of a configuration item (string or symbol)
|
358
|
+
* If a second parameter is present, it is the new value (the old value is returned)
|
359
|
+
* If there is no second parameter, it only returns the current value.
|
360
|
+
|
361
|
+
Not all of calc's configuration is implemented (and only onese related to maths functions will be). The defaults are the same as using calc with no command line options. The current set are:
|
362
|
+
|
363
|
+
Parameter | Default | Meaning
|
364
|
+
--------- | ------- | -------
|
365
|
+
appr | 24 | rounding mode for `appr`
|
366
|
+
cfappr | 0 | rounding mode for `cfappr`
|
367
|
+
display | 20 | number of digits when converting to string (does NOT affect internal value)
|
368
|
+
epsilon | 1e-20 | default precision for transcendental functions
|
369
|
+
mod | 0 | rounding mode for `%`, default for `mod`
|
370
|
+
mode | :real | default output mode when converting to string
|
371
|
+
quo | 2 | rounding mode for `quo`
|
372
|
+
quomod | 0 | rounding mode for `quomod`
|
373
|
+
round | 24 | rounding mode for `bround` and `round`
|
374
|
+
sqrt | 24 | rounding mode and sign for `sqrt`
|
375
|
+
|
376
|
+
For more details of these, type "help config" in calc.
|
377
|
+
|
378
|
+
## Differences from Calc
|
379
|
+
|
380
|
+
For people familiar with the command line interface to calc, here are some important differences to make this library more ruby-ish:
|
381
|
+
|
382
|
+
### Literals
|
383
|
+
|
384
|
+
In calc, a decimal literal is interpreted as a rational number, whereas in ruby it will be a floating point number. In fact, libcalc does not use or allow C types float or double anywhere in its API.
|
385
|
+
|
386
|
+
Although you can initialize Calc::Q objects from ruby floats, their internal representation will actually be a rational number as close as possible to the ruby float, which is not necessarily the same as what you typed. This is also true for scientific notation.
|
387
|
+
|
388
|
+
```ruby
|
389
|
+
Calc::Q(1.2) #=> Calc::Q(~1.19999999999999995559)
|
390
|
+
Calc::Q(1.2).to_s(:frac) #=> "5404319552844595/4503599627370496"
|
391
|
+
Calc::Q(1e-5) #=> Calc::Q(~0.00001000000000000000)
|
392
|
+
Calc::Q(1e-5).to_s(:frac) #=> "5902958103587057/590295810358705651712"
|
393
|
+
```
|
394
|
+
|
395
|
+
In most cases where you can provide a numeric argument to a method, ruby-calc allows a string. The string will be parsed using libcalc, so the exact intended value is stored.
|
396
|
+
|
397
|
+
```ruby
|
398
|
+
Calc::Q("1.2") #=> Calc::Q(1.2)
|
399
|
+
Calc::Q("1e-5") #=> Calc::Q(0.00001)
|
400
|
+
```
|
401
|
+
|
402
|
+
### Output Parameters
|
403
|
+
|
404
|
+
Ruby doesn't have output parameters; for functions which in calc modify their parameters, ruby-calc instead returns values, eg:
|
405
|
+
|
406
|
+
```ruby
|
407
|
+
q, r = Calc::Q(a).quomod(b) # in calc: quomod(a, b, q, r)
|
408
|
+
# the actual calc return value is not available
|
409
|
+
```
|
410
|
+
|
411
|
+
### Predicate Functions and Truthiness
|
412
|
+
|
413
|
+
Predicate functions (usually starting with "is") return 0 or 1 indicating false or true, matching the original calc version. In ruby, 0 is true so you shouldn't use these in a boolean context. Each function has a more rubyish version named with a question mark which returns true or false.
|
414
|
+
|
415
|
+
If in calc you would do this:
|
416
|
+
|
417
|
+
```
|
418
|
+
if (iseven(q)) {
|
419
|
+
something();
|
420
|
+
}
|
421
|
+
```
|
422
|
+
|
423
|
+
Three options in ruby-calc:
|
424
|
+
|
425
|
+
```ruby
|
426
|
+
# preferred
|
427
|
+
if q.even?
|
428
|
+
something
|
429
|
+
end
|
430
|
+
|
431
|
+
# or
|
432
|
+
if q.iseven == 1
|
433
|
+
something
|
434
|
+
end
|
435
|
+
|
436
|
+
# or
|
437
|
+
if Calc.iseven(q) == 1
|
438
|
+
something
|
439
|
+
end
|
440
|
+
```
|
441
|
+
|
442
|
+
These builtins work this way:
|
443
|
+
* bit / bit?
|
444
|
+
* iseven / even?
|
445
|
+
* isimag / imag?
|
446
|
+
* isint / int?
|
447
|
+
* ismult / mult?
|
448
|
+
* isodd / odd?
|
449
|
+
* isprime / prime?
|
450
|
+
* isreal / real?
|
451
|
+
* isrel / rel?
|
452
|
+
* meq / meq?
|
453
|
+
* mne / mne?
|
454
|
+
* ptest / ptest?
|
455
|
+
|
456
|
+
`isimag` isn't a real calc builtin but it is included anyway.
|
457
|
+
|
458
|
+
### xor / power
|
459
|
+
|
460
|
+
In calc, the `^` operator raises to a power. In ruby, it is a bitwise exclusive or operator.
|
461
|
+
|
462
|
+
If you want to raise to a power, use `**`, which behaves the same in both calc and ruby. Alternatively, you can use the methods named `power` and `xor`.
|
463
|
+
|
464
|
+
### Other Differences
|
465
|
+
|
466
|
+
* Calc builtins `mod`, `quo`, `quomod` and operator `%` allow division by zero; ruby-calc raises a ZeroDivisonError in these cases
|
467
|
+
* `estr` return format is different, intended to be eval'd by ruby rather than calc
|
468
|
+
* `nextcand` and `prevcand` return nil instead of 0 if a candidate prime is not found
|
469
|
+
* `prevprime` returns nil instead of 0 for arguments <= 2
|
470
|
+
* the "error" argument of `factor`, `nextprime`, `prevprime` and `pix` is not implemented. errors in these methods will always raise exceptions instead of returning the supplied error value.
|
471
|
+
* REDC related functions (`freeredc`, `rcin`, `rcmul`, `rcout`, `rcpow`, `rcsq` are not implemented for now since there are alternatives and anyone wanting the faster modular arithmetic probably shouldn't be using ruby-calc
|
472
|
+
* Non-maths builtin functions are not implemented - use the normal ruby way of doing that
|
473
|
+
* Not all configuration items are implemented (and only ones related to maths will be)
|
474
|
+
* You can't define/call calc functions (ie, eval() is not implemented)
|
475
|
+
* Libcalc provides an integer type (ZVALUE) which ruby-calc doesn't provide access to (because ruby already has arbitrary size integers and libcalc's interesting functions are all for Rational or Complex numbers)
|
476
|
+
|
477
|
+
## Licence
|
478
|
+
|
479
|
+
This gem is under the MIT licence (see LICENSE.txt). However libcalc is distributed under the LGPL. Therefore a compiled version of this library (`calc.so` or `calc.bundle`) may also be under the LGPL.
|
480
|
+
|
481
|
+
## Development
|
482
|
+
|
483
|
+
ruby-calc requires ruby 2.0.0 or newer.
|
484
|
+
|
485
|
+
Make sure you have calc development headers installed (yum install calc-dev / apt-get install apcalc-devel, or have manually installed calc).
|
486
|
+
|
487
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `bin/console` for an interactive prompt that will allow you to experiment.
|
488
|
+
|
489
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release` to create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
490
|
+
|
491
|
+
## Contributing
|
492
|
+
|
493
|
+
1. Fork it ( https://github.com/timpeters/ruby-calc/fork )
|
494
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
495
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
496
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
497
|
+
5. Create a new Pull Request
|