gmp 0.4.0-x86-mingw32
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +109 -0
- data/INSTALL +4 -0
- data/README.rdoc +357 -0
- data/benchmark/COPYING +674 -0
- data/benchmark/README +75 -0
- data/benchmark/divide +34 -0
- data/benchmark/gcd +38 -0
- data/benchmark/gexpr +0 -0
- data/benchmark/gexpr.c +359 -0
- data/benchmark/multiply +44 -0
- data/benchmark/rsa +93 -0
- data/benchmark/runbench +147 -0
- data/benchmark/version +1 -0
- data/ext/extconf.rb +30 -0
- data/ext/gmp.c +197 -0
- data/ext/gmpbench_timing.c +80 -0
- data/ext/gmpf.c +595 -0
- data/ext/gmpf.h +144 -0
- data/ext/gmpq.c +780 -0
- data/ext/gmpq.h +12 -0
- data/ext/gmprandstate.c +224 -0
- data/ext/gmpz.c +1968 -0
- data/ext/gmpz.h +20 -0
- data/ext/libgmp-10.dll +0 -0
- data/ext/ruby_gmp.h +243 -0
- data/ext/takeover.h +36 -0
- data/manual.pdf +0 -0
- data/manual.tex +804 -0
- data/test/README +34 -0
- data/test/tc_cmp.rb +74 -0
- data/test/tc_division.rb +109 -0
- data/test/tc_f_arithmetics_coersion.rb +71 -0
- data/test/tc_f_precision.rb +48 -0
- data/test/tc_fib_fac_nextprime.rb +51 -0
- data/test/tc_floor_ceil_truncate.rb +21 -0
- data/test/tc_logical_roots.rb +48 -0
- data/test/tc_q.rb +27 -0
- data/test/tc_q_basic.rb +41 -0
- data/test/tc_random.rb +54 -0
- data/test/tc_sgn_neg_abs.rb +47 -0
- data/test/tc_swap.rb +19 -0
- data/test/tc_z.rb +71 -0
- data/test/tc_z_basic.rb +35 -0
- data/test/tc_z_exponentiation.rb +22 -0
- data/test/tc_z_gcd_lcm_invert.rb +57 -0
- data/test/tc_z_jac_leg_rem.rb +73 -0
- data/test/tc_z_logic.rb +54 -0
- data/test/tc_z_shifts_last_bits.rb +22 -0
- data/test/tc_z_to_d_to_i.rb +24 -0
- data/test/tc_zerodivisionexceptions.rb +17 -0
- data/test/test-12.rb +14 -0
- data/test/test-19.rb +13 -0
- data/test/test-20.rb +29 -0
- data/test/test-21.rb +37 -0
- data/test/test-22.rb +12 -0
- data/test/test-23.rb +11 -0
- data/test/test_helper.rb +8 -0
- data/test/unit_tests.rb +39 -0
- metadata +115 -0
data/ext/gmpz.h
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
#ifndef _GMPZ_H_
|
2
|
+
#define _GMPZ_H_
|
3
|
+
|
4
|
+
/*
|
5
|
+
* gmpz.h
|
6
|
+
*
|
7
|
+
* This file contains GMP::Z method definitions.
|
8
|
+
*/
|
9
|
+
|
10
|
+
#include <ruby_gmp.h>
|
11
|
+
|
12
|
+
#define DEFUN_INT_COND_P(fname,mpz_fname) \
|
13
|
+
static VALUE r_gmpz_##fname(VALUE self) \
|
14
|
+
{ \
|
15
|
+
MP_INT *self_val; \
|
16
|
+
mpz_get_struct(self, self_val); \
|
17
|
+
return mpz_fname(self_val)?Qtrue:Qfalse; \
|
18
|
+
}
|
19
|
+
|
20
|
+
#endif
|
data/ext/libgmp-10.dll
ADDED
Binary file
|
data/ext/ruby_gmp.h
ADDED
@@ -0,0 +1,243 @@
|
|
1
|
+
#ifndef _RUBY_GMP_H_
|
2
|
+
#define _RUBY_GMP_H_
|
3
|
+
|
4
|
+
#include <stdio.h>
|
5
|
+
#include <ruby.h>
|
6
|
+
#ifndef _GNU_SOURCE
|
7
|
+
#define _GNU_SOURCE
|
8
|
+
#endif
|
9
|
+
#include <gmp.h>
|
10
|
+
|
11
|
+
#ifdef MPFR
|
12
|
+
|
13
|
+
#ifdef HAVE_MPFR_H
|
14
|
+
#include <mpfr.h>
|
15
|
+
#endif /* HAVE_MPFR_H */
|
16
|
+
|
17
|
+
#ifdef HAVE_MPF2MPFR_H
|
18
|
+
#include <mpf2mpfr.h>
|
19
|
+
#endif /* HAVE_MPF2MPFR_H */
|
20
|
+
|
21
|
+
#endif /* MPFR */
|
22
|
+
|
23
|
+
#include <stdlib.h>
|
24
|
+
|
25
|
+
/*
|
26
|
+
MP_INT*, MP_RAT* and MP_FLOAT* are used because they don't have side-effects
|
27
|
+
of single-element arrays mp*_t
|
28
|
+
|
29
|
+
MP_FLOAT is defined here, as it's commented out in gmp.h
|
30
|
+
*/
|
31
|
+
#if defined(MPFR) && defined(HAVE_MPFR_H)
|
32
|
+
typedef __mpfr_struct MP_FLOAT;
|
33
|
+
#else
|
34
|
+
typedef __mpf_struct MP_FLOAT;
|
35
|
+
#endif /* HAVE_MPF2MPFR_H */
|
36
|
+
|
37
|
+
/*
|
38
|
+
I don't like this solution, because in gmp.h, all of these typedefs are
|
39
|
+
marked with "gmp 1 source compatibility". :(.
|
40
|
+
*/
|
41
|
+
typedef __gmp_randstate_struct MP_RANDSTATE;
|
42
|
+
|
43
|
+
#define mpz_get_struct(ruby_var,c_var) { Data_Get_Struct(ruby_var, MP_INT, c_var); }
|
44
|
+
#define mpq_get_struct(ruby_var,c_var) { Data_Get_Struct(ruby_var, MP_RAT, c_var); }
|
45
|
+
#define mpf_get_struct(ruby_var,c_var) { Data_Get_Struct(ruby_var, MP_FLOAT, c_var); }
|
46
|
+
#define mprandstate_get_struct(ruby_var,c_var) { Data_Get_Struct(ruby_var, MP_RANDSTATE, c_var); }
|
47
|
+
#define mpf_get_struct_prec(ruby_var,c_var,prec) { mpf_get_struct(ruby_var,c_var); prec = mpf_get_prec(c_var); }
|
48
|
+
#define mpz_make_struct(ruby_var,c_var) { ruby_var = Data_Make_Struct(cGMP_Z, MP_INT, 0, r_gmpz_free, c_var); }
|
49
|
+
#define mpq_make_struct(ruby_var,c_var) { ruby_var = Data_Make_Struct(cGMP_Q, MP_RAT, 0, r_gmpq_free, c_var); }
|
50
|
+
#define mpf_make_struct(ruby_var,c_var) { ruby_var = Data_Make_Struct(cGMP_F, MP_FLOAT, 0, r_gmpf_free, c_var); }
|
51
|
+
#define mprandstate_make_struct(ruby_var,c_var) { ruby_var = Data_Make_Struct(cGMP_RandState, MP_RANDSTATE, 0, r_gmprandstate_free, c_var); }
|
52
|
+
#define mpz_make_struct_init(ruby_var,c_var) { mpz_make_struct(ruby_var,c_var); mpz_init (c_var); }
|
53
|
+
#define mpq_make_struct_init(ruby_var,c_var) { mpq_make_struct(ruby_var,c_var); mpq_init (c_var); }
|
54
|
+
#define mpf_make_struct_init(ruby_var,c_var,prec) { mpf_make_struct(ruby_var,c_var); mpf_init2 (c_var,prec); }
|
55
|
+
#define BIGNUM_P(value) (TYPE(value) == T_BIGNUM)
|
56
|
+
#define FLOAT_P(value) (TYPE(value) == T_FLOAT)
|
57
|
+
#define STRING_P(value) (TYPE(value) == T_STRING)
|
58
|
+
#define GMPZ_P(value) (rb_obj_is_instance_of(value, cGMP_Z) == Qtrue)
|
59
|
+
#define GMPQ_P(value) (rb_obj_is_instance_of(value, cGMP_Q) == Qtrue)
|
60
|
+
#define GMPF_P(value) (rb_obj_is_instance_of(value, cGMP_F) == Qtrue)
|
61
|
+
#define mpz_set_bignum(var_mpz,var_bignum) \
|
62
|
+
mpz_set_str (var_mpz, STR2CSTR (rb_funcall (var_bignum, rb_intern ("to_s"), 0)), 0);
|
63
|
+
#define mpz_temp_alloc(var) { var=malloc(sizeof(MP_INT)); }
|
64
|
+
#define mpz_temp_init(var) { mpz_temp_alloc(var); mpz_init(var); }
|
65
|
+
#define mpz_temp_from_bignum(var,var_bignum) \
|
66
|
+
{ mpz_temp_alloc(var); mpz_init_set_str(var, STR2CSTR(rb_funcall(var_bignum, rb_intern("to_s"), 0)), 0); }
|
67
|
+
#define mpz_temp_free(var) { mpz_clear(var); free(var); }
|
68
|
+
#define mpf_temp_alloc(var) { var=malloc(sizeof(MP_FLOAT)); }
|
69
|
+
#define mpf_temp_init(var,prec) { mpf_temp_alloc(var); mpf_init2(var,prec); }
|
70
|
+
#define mpf_temp_free(var) { mpf_clear(var); free(var); }
|
71
|
+
#define prec_max(prec,var) {if(mpf_get_prec(var) > prec) prec = mpf_get_prec(var); }
|
72
|
+
|
73
|
+
#define EXPECTED_ZQFXBD "Expected GMP::Z, GMP::Q, GMP::F, Fixnum, Bignum or Float"
|
74
|
+
#define EXPECTED_ZQFXB "Expected GMP::Z, GMP::Q, GMP::F, Fixnum or Bignum"
|
75
|
+
#define EXPECTED_ZXB "Expected GMP::Z, Fixnum or Bignum"
|
76
|
+
#define EXPECTED_ZX "Expected GMP::Z or Fixnum"
|
77
|
+
#define EXPECTED_X "Expected Fixnum"
|
78
|
+
#define EXPECTED_Z "Expected GMP::Z"
|
79
|
+
#define typeerror(expected) rb_raise(rb_eTypeError, EXPECTED_##expected)
|
80
|
+
#define typeerror_as(expected, argname) rb_raise(rb_eTypeError, EXPECTED_##expected " as " argname)
|
81
|
+
|
82
|
+
//should change exception type
|
83
|
+
#define not_yet rb_raise(rb_eTypeError,"Not implemented yet")
|
84
|
+
|
85
|
+
extern VALUE mGMP, cGMP_Z, cGMP_Q, cGMP_F, cGMP_RandState;
|
86
|
+
|
87
|
+
extern void r_gmpz_free(void *ptr);
|
88
|
+
extern void r_gmpq_free(void *ptr);
|
89
|
+
extern void r_gmpf_free(void *ptr);
|
90
|
+
extern void r_gmprandstate_free(void *ptr);
|
91
|
+
|
92
|
+
|
93
|
+
/* from gmpz.h */
|
94
|
+
|
95
|
+
// Initializing, Assigning Integers
|
96
|
+
extern VALUE r_gmpzsg_new(int argc, VALUE *argv, VALUE klass);
|
97
|
+
extern VALUE r_gmpz_initialize(int argc, VALUE *argv, VALUE self);
|
98
|
+
extern void mpz_set_value(MP_INT *target, VALUE source);
|
99
|
+
extern VALUE r_gmpmod_z(int argc, VALUE *argv, VALUE module);
|
100
|
+
extern VALUE r_gmpz_swap(VALUE self, VALUE arg);
|
101
|
+
|
102
|
+
// Converting Integers
|
103
|
+
extern VALUE r_gmpz_to_i(VALUE self);
|
104
|
+
extern VALUE r_gmpz_to_d(VALUE self);
|
105
|
+
extern VALUE r_gmpz_to_s(int argc, VALUE *argv, VALUE self);
|
106
|
+
|
107
|
+
// Integer Arithmetic
|
108
|
+
extern VALUE r_gmpz_add(VALUE self, VALUE arg);
|
109
|
+
extern VALUE r_gmpz_add_self(VALUE self, VALUE arg);
|
110
|
+
extern VALUE r_gmpz_sub(VALUE self, VALUE arg);
|
111
|
+
extern VALUE r_gmpz_sub_self(VALUE self, VALUE arg);
|
112
|
+
extern VALUE r_gmpz_mul(VALUE self, VALUE arg);
|
113
|
+
|
114
|
+
// Integer Division
|
115
|
+
extern VALUE r_gmpz_mod(VALUE self, VALUE arg);
|
116
|
+
|
117
|
+
// Integer Exponentiation
|
118
|
+
extern VALUE r_gmpzsg_pow(VALUE klass, VALUE base, VALUE exp);
|
119
|
+
|
120
|
+
// Number Theoretic Functions
|
121
|
+
extern VALUE r_gmpz_is_probab_prime(int argc, VALUE* argv, VALUE self);
|
122
|
+
extern VALUE r_gmpz_gcd(VALUE self, VALUE arg);
|
123
|
+
extern VALUE r_gmpz_invert(VALUE self, VALUE arg);
|
124
|
+
extern VALUE r_gmpz_jacobi(VALUE self, VALUE b);
|
125
|
+
extern VALUE r_gmpzsg_jacobi(VALUE klass, VALUE a, VALUE b);
|
126
|
+
extern VALUE r_gmpz_legendre(VALUE self, VALUE p);
|
127
|
+
extern VALUE r_gmpz_remove(VALUE self, VALUE arg);
|
128
|
+
|
129
|
+
// Integer Comparisons
|
130
|
+
extern VALUE r_gmpz_eq(VALUE self, VALUE arg);
|
131
|
+
extern VALUE r_gmpz_cmp(VALUE self, VALUE arg);
|
132
|
+
extern VALUE r_gmpz_cmpabs(VALUE self, VALUE arg);
|
133
|
+
|
134
|
+
// Miscelaneous Integer Functions
|
135
|
+
extern VALUE r_gmpz_sizeinbase(VALUE self, VALUE base);
|
136
|
+
extern VALUE r_gmpz_size_in_bin(VALUE self);
|
137
|
+
|
138
|
+
// _unsorted_
|
139
|
+
extern VALUE r_gmpz_div(VALUE self, VALUE arg);
|
140
|
+
extern VALUE r_gmpz_popcount(VALUE self);
|
141
|
+
extern VALUE r_gmpz_setbit(VALUE self, VALUE bitnr, VALUE set_to);
|
142
|
+
extern VALUE r_gmpz_getbit(VALUE self, VALUE bitnr);
|
143
|
+
extern VALUE r_gmpz_scan0(VALUE self, VALUE bitnr);
|
144
|
+
extern VALUE r_gmpz_scan1(VALUE self, VALUE bitnr);
|
145
|
+
extern VALUE r_gmpz_powm(VALUE self, VALUE exp, VALUE mod);
|
146
|
+
extern VALUE r_gmpz_sgn(VALUE self);
|
147
|
+
extern int mpz_cmp_value(MP_INT *OP, VALUE arg);
|
148
|
+
|
149
|
+
|
150
|
+
|
151
|
+
/* from gmpq.h */
|
152
|
+
|
153
|
+
// Initializing Rationals
|
154
|
+
extern VALUE r_gmpqsg_new(int argc, VALUE *argv, VALUE klass);
|
155
|
+
extern VALUE r_gmpmod_q(int argc, VALUE *argv, VALUE module);
|
156
|
+
extern VALUE r_gmpq_swap(VALUE self, VALUE arg);
|
157
|
+
|
158
|
+
// Rational Conversions
|
159
|
+
extern VALUE r_gmpq_to_d(VALUE self);
|
160
|
+
extern VALUE r_gmpq_to_s(VALUE self);
|
161
|
+
|
162
|
+
// Rational Arithmetic
|
163
|
+
extern VALUE r_gmpq_add(VALUE self, VALUE arg);
|
164
|
+
extern VALUE r_gmpq_sub(VALUE self, VALUE arg);
|
165
|
+
extern VALUE r_gmpq_mul(VALUE self, VALUE arg);
|
166
|
+
extern VALUE r_gmpq_div(VALUE self, VALUE arg);
|
167
|
+
extern VALUE r_gmpq_neg(VALUE self);
|
168
|
+
extern VALUE r_gmpq_neg_self(VALUE self);
|
169
|
+
extern VALUE r_gmpq_abs(VALUE self);
|
170
|
+
extern VALUE r_gmpq_abs_self(VALUE self);
|
171
|
+
extern VALUE r_gmpq_inv(VALUE self);
|
172
|
+
extern VALUE r_gmpq_inv_self(VALUE self);
|
173
|
+
|
174
|
+
// Comparing Rationals
|
175
|
+
extern VALUE r_gmpq_eq(VALUE self, VALUE arg);
|
176
|
+
extern VALUE r_gmpq_cmp(VALUE self, VALUE arg);
|
177
|
+
extern int mpq_cmp_value(MP_RAT *OP, VALUE arg);
|
178
|
+
extern VALUE r_gmpq_sgn(VALUE self);
|
179
|
+
|
180
|
+
// Applying Integer Functions
|
181
|
+
extern VALUE r_gmpq_num(VALUE self);
|
182
|
+
extern VALUE r_gmpq_den(VALUE self);
|
183
|
+
|
184
|
+
// _unsorted_
|
185
|
+
|
186
|
+
|
187
|
+
/* from gmpf.h */
|
188
|
+
|
189
|
+
// Initializing, Assigning Floats
|
190
|
+
extern VALUE r_gmpfsg_new(int argc, VALUE *argv, VALUE klass);
|
191
|
+
extern VALUE r_gmpf_initialize(int argc, VALUE *argv, VALUE self);
|
192
|
+
extern void mpf_set_value(MP_FLOAT *self_val, VALUE arg);
|
193
|
+
extern VALUE r_gmpmod_f(int argc, VALUE *argv, VALUE module);
|
194
|
+
|
195
|
+
// Converting Floats
|
196
|
+
extern VALUE r_gmpf_to_d(VALUE self);
|
197
|
+
extern VALUE r_gmpf_to_s(VALUE self);
|
198
|
+
|
199
|
+
// Float Arithmetic
|
200
|
+
extern VALUE r_gmpf_add(VALUE self, VALUE arg);
|
201
|
+
extern VALUE r_gmpf_sub(VALUE self, VALUE arg);
|
202
|
+
extern VALUE r_gmpf_mul(VALUE self, VALUE arg);
|
203
|
+
extern VALUE r_gmpf_div(VALUE self, VALUE arg);
|
204
|
+
|
205
|
+
// Float Comparison
|
206
|
+
extern VALUE r_gmpf_eq(VALUE self, VALUE arg);
|
207
|
+
extern VALUE r_gmpf_cmp(VALUE self, VALUE arg);
|
208
|
+
extern int mpf_cmp_value(MP_FLOAT *OP, VALUE arg);
|
209
|
+
|
210
|
+
// _unsorted_
|
211
|
+
extern VALUE r_gmpf_sgn(VALUE self);
|
212
|
+
extern VALUE r_gmpf_get_prec(VALUE self);
|
213
|
+
|
214
|
+
|
215
|
+
/* from gmprandstate.h */
|
216
|
+
|
217
|
+
// Random State Initialization
|
218
|
+
extern VALUE r_gmprandstatesg_new(int argc, VALUE *argv, VALUE klass);
|
219
|
+
extern VALUE r_gmprandstate_initialize(int argc, VALUE *argv, VALUE self);
|
220
|
+
extern VALUE r_gmpmod_randstate(int argc, VALUE *argv, VALUE module);
|
221
|
+
|
222
|
+
// Random State Seeding
|
223
|
+
extern VALUE r_gmprandstate_seed(VALUE self, VALUE arg);
|
224
|
+
|
225
|
+
// Integer Random Numbers
|
226
|
+
extern VALUE r_gmprandstate_urandomb(VALUE self, VALUE arg);
|
227
|
+
|
228
|
+
|
229
|
+
/* from gmpbench_timing.c */
|
230
|
+
|
231
|
+
// GMPbench Timing
|
232
|
+
extern VALUE r_gmpmod_cputime(VALUE self);
|
233
|
+
extern VALUE r_gmpmod_time(VALUE self);
|
234
|
+
|
235
|
+
|
236
|
+
|
237
|
+
extern void init_gmpz();
|
238
|
+
extern void init_gmpq();
|
239
|
+
extern void init_gmpf();
|
240
|
+
extern void init_gmprandstate();
|
241
|
+
extern void init_gmpbench_timing();
|
242
|
+
|
243
|
+
#endif
|
data/ext/takeover.h
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
#define DEFUN_TAKEOVER_LOGIC(fname, mpz_fname, old_fname) \
|
2
|
+
static VALUE takeover_fixnum_##fname(int argc, VALUE *argv, VALUE self) \
|
3
|
+
{ \
|
4
|
+
MP_INT *res_val, *arg_val; \
|
5
|
+
VALUE res; \
|
6
|
+
\
|
7
|
+
if (argc != 1 || !GMPZ_P(argv[0])) { \
|
8
|
+
return rb_funcall2 (self, rb_intern (old_fname), argc, argv); \
|
9
|
+
} else { \
|
10
|
+
mpz_make_struct(res, res_val); \
|
11
|
+
mpz_get_struct(argv[0], arg_val); \
|
12
|
+
mpz_init_set_si (res_val, FIX2INT(self)); \
|
13
|
+
mpz_fname (res_val, res_val, arg_val); \
|
14
|
+
return res; \
|
15
|
+
} \
|
16
|
+
} \
|
17
|
+
\
|
18
|
+
static VALUE takeover_bignum_##fname(int argc, VALUE *argv, VALUE self) \
|
19
|
+
{\
|
20
|
+
MP_INT *res_val, *arg_val; \
|
21
|
+
VALUE res; \
|
22
|
+
\
|
23
|
+
if (argc != 1 || !GMPZ_P(argv[0])) { \
|
24
|
+
return rb_funcall2 (self, rb_intern (old_fname), argc, argv); \
|
25
|
+
} else { \
|
26
|
+
mpz_get_struct(argv[0], arg_val); \
|
27
|
+
mpz_make_struct_init(res, res_val); \
|
28
|
+
mpz_set_bignum (res_val, self); \
|
29
|
+
mpz_fname (res_val, res_val, arg_val); \
|
30
|
+
return res; \
|
31
|
+
} \
|
32
|
+
}
|
33
|
+
|
34
|
+
DEFUN_TAKEOVER_LOGIC(and, mpz_and, "old_and")
|
35
|
+
DEFUN_TAKEOVER_LOGIC(or, mpz_ior, "old_or")
|
36
|
+
DEFUN_TAKEOVER_LOGIC(xor, mpz_xor, "old_xor")
|
data/manual.pdf
ADDED
Binary file
|
data/manual.tex
ADDED
@@ -0,0 +1,804 @@
|
|
1
|
+
\documentclass[pdftex,10pt]{article}
|
2
|
+
\usepackage{amsmath,amsfonts,url}
|
3
|
+
\usepackage[pdftex]{graphicx}
|
4
|
+
\usepackage{booktabs}
|
5
|
+
\usepackage{url}
|
6
|
+
\setlength{\parindent}{0pt}
|
7
|
+
\def\cour{\fontfamily{pcr}\selectfont}
|
8
|
+
\usepackage[top=1in, bottom=0.8in, left=0.8in, right=0.8in]{geometry}
|
9
|
+
\setcounter{tocdepth}{3}
|
10
|
+
\newlength{\titrwidth}
|
11
|
+
\setlength{\titrwidth}{\textwidth}
|
12
|
+
\addtolength{\titrwidth}{-1.2in}
|
13
|
+
\newlength{\methwidth}
|
14
|
+
\setlength{\methwidth}{0.8in}
|
15
|
+
\newlength{\defnwidth}
|
16
|
+
\setlength{\defnwidth}{\textwidth}
|
17
|
+
\addtolength{\defnwidth}{-1.2in}
|
18
|
+
\addtolength{\heavyrulewidth}{\heavyrulewidth}
|
19
|
+
\def\qquad{\quad\quad}
|
20
|
+
\def\qqqquad{\quad\quad\quad\quad}
|
21
|
+
\def\cc{\colon\colon}
|
22
|
+
\def\gmpz{\textit{GMP::Z}}
|
23
|
+
\def\gmprandstate{\textit{GMP::RandState\ }}
|
24
|
+
\frenchspacing
|
25
|
+
\begin{document}
|
26
|
+
|
27
|
+
\begin{tabular}{p{1.0in} p{\titrwidth}}
|
28
|
+
\huge{gmp} &\\
|
29
|
+
\midrule[3pt]
|
30
|
+
\multicolumn{2}{r}{\large{Ruby bindings to the GMP library}}\\
|
31
|
+
\multicolumn{2}{r}{\large{Edition 0.4.0}}\\
|
32
|
+
\multicolumn{2}{r}{\large{26 February 2010}}
|
33
|
+
\end{tabular}
|
34
|
+
|
35
|
+
\vfill
|
36
|
+
\large{written by Sam Rawlins}\\
|
37
|
+
\large{with extensive quoting from the GMP Manual}
|
38
|
+
\newpage
|
39
|
+
|
40
|
+
\vfill
|
41
|
+
This manual describes how to use the gmp Ruby gem, which provides bindings to
|
42
|
+
the GNU multiple precision arithmetic library, version 4.3.x or 5.0.x.\\
|
43
|
+
\\
|
44
|
+
Copyright 2009 Sam Rawlins.\\
|
45
|
+
No license yet.
|
46
|
+
\newpage
|
47
|
+
|
48
|
+
\tableofcontents
|
49
|
+
\newpage
|
50
|
+
|
51
|
+
\section{Introduction to GNU MP}
|
52
|
+
|
53
|
+
This entire page is copied verbatim from the GMP Manual.\\\\
|
54
|
+
|
55
|
+
GNU MP is a portable library written in C for arbitrary precision arithmetic on
|
56
|
+
integers, rational numbers, and floating-point numbers. It aims to provide the
|
57
|
+
fastest possible arithmetic for all applications that need higher precision
|
58
|
+
than is directly supported by the basic C types.\\
|
59
|
+
\\
|
60
|
+
Many applications use just a few hundred bits of precision; but some
|
61
|
+
applications may need thousands or even millions of bits. GMP is designed to
|
62
|
+
give good performance for both, by choosing algorithms based on the sizes of
|
63
|
+
the operands, and by carefully keeping the overhead at a minimum.\\
|
64
|
+
\\
|
65
|
+
The speed of GMP is achieved by using fullwords as the basic arithmetic type,
|
66
|
+
by using sophisticated algorithms, by including carefully optimized assembly
|
67
|
+
code for the most common inner loops for many different CPUs, and by a general
|
68
|
+
emphasis on speed (as opposed to simplicity or elegance).\\
|
69
|
+
\\
|
70
|
+
There is assembly code for these CPUs: ARM, DEC Alpha 21064, 21164, and 21264,
|
71
|
+
AMD 29000, AMD K6, K6-2, Athlon, and Athlon64, Hitachi SuperH and SH-2, HPPA
|
72
|
+
1.0, 1.1, and 2.0, Intel Pentium, Pentium Pro/II/III, Pentium 4, generic x86,
|
73
|
+
Intel IA-64, i960, Motorola MC68000, MC68020, MC88100, and MC88110,
|
74
|
+
Motorola/IBM PowerPC 32 and 64, National NS32000, IBM POWER, MIPS R3000, R4000,
|
75
|
+
SPARCv7, SuperSPARC, generic SPARCv8, UltraSPARC, DEC VAX, and Zilog Z8000.
|
76
|
+
Some optimizations also for Cray vector systems, Clipper, IBM ROMP (RT), and
|
77
|
+
Pyramid AP/XP.\\
|
78
|
+
\\
|
79
|
+
For up-to-date information on GMP, please see the GMP web pages at\\
|
80
|
+
\setlength{\parindent}{0.25in}
|
81
|
+
\texttt{http://gmplib.org/}
|
82
|
+
\setlength{\parindent}{0in}
|
83
|
+
\\
|
84
|
+
|
85
|
+
The latest version of the library is available at\\
|
86
|
+
\setlength{\parindent}{0.25in}
|
87
|
+
\texttt{ftp://ftp.gnu.org/gnu/gmp/}\\
|
88
|
+
\setlength{\parindent}{0in}
|
89
|
+
\\
|
90
|
+
|
91
|
+
Many sites around the world mirror '\texttt{ftp.gnu.org}', please use a mirror
|
92
|
+
near you, see \texttt{http://www.gnu.org/order/ftp.html} for a full list.\\
|
93
|
+
\\
|
94
|
+
There are three public mailing lists of interest. One for release
|
95
|
+
announcements, one for general questions and discussions about usage of the GMP
|
96
|
+
library, and one for bug reports. For more information, see\\
|
97
|
+
\\
|
98
|
+
\texttt{http://gmplib.org/mailman/listinfo/}.\\
|
99
|
+
\\
|
100
|
+
The proper place for bug reports is gmp-bugs@gmplib.org. See Chapter 4
|
101
|
+
[Reporting Bugs], page 28 for information about reporting bugs.
|
102
|
+
|
103
|
+
\section{Introduction to the gmp gem}
|
104
|
+
|
105
|
+
The gmp Ruby gem is a Ruby library that provides bindings to GMP. The gem is
|
106
|
+
incomplete, and will likely only include a subset of the GMP functions. It is
|
107
|
+
built as a C extension for ruby, interacting with gmp.h. The gmp gem is not
|
108
|
+
endorsed or supported by GNU or the GMP team. The gmp gem also does not ship
|
109
|
+
with GMP, so GMP must be compiled separately.
|
110
|
+
|
111
|
+
\section{Installing the gmp gem}
|
112
|
+
|
113
|
+
\subsection{Prerequisites}
|
114
|
+
OK. First, we've got a few requirements. To install the gmp gem, you need one
|
115
|
+
of the following versions of Ruby:
|
116
|
+
\begin{itemize}
|
117
|
+
\item (MRI) Ruby 1.8.6 - tested lightly.
|
118
|
+
\item (MRI) Ruby 1.8.7 - tested seriously.
|
119
|
+
\item (MRI) Ruby 1.9.1 - tested seriously.
|
120
|
+
\end{itemize}
|
121
|
+
As you can see only Matz's Ruby Interpreter (MRI) is supported. I haven't even
|
122
|
+
put a thought into trying other interpreters/VMs. I intend to look into FFI,
|
123
|
+
which supposedly will allow me to load this extension into JRuby and Rubinius,
|
124
|
+
not sure about others...\\
|
125
|
+
|
126
|
+
Next is the platform, the combination of the architecture (processor) and OS.
|
127
|
+
As far as I can tell, if you can compile GMP and Ruby on a given platform, you
|
128
|
+
can use the gmp gem there too. Please report problems with that hypothesis.\\
|
129
|
+
|
130
|
+
Lastly, GMP. GMP must be compiled and working. "and working" means you ran "make
|
131
|
+
check" while installing GMP. The following versions of GMP have been tested:
|
132
|
+
\begin{itemize}
|
133
|
+
\item GMP 4.3.1
|
134
|
+
\item GMP 4.3.2
|
135
|
+
\item GMP 5.0.0
|
136
|
+
\item GMP 5.0.1
|
137
|
+
\end{itemize}
|
138
|
+
|
139
|
+
That's all. I don't intend to test any older versions, maybe 4.3.0 for
|
140
|
+
completeness.\\
|
141
|
+
|
142
|
+
Here is a table of the exact environments on which I have tested the gmp gem:\\\\
|
143
|
+
|
144
|
+
\begin{tabular}{lrr} \hline
|
145
|
+
Platform & Ruby & GMP \\ \midrule[1pt]
|
146
|
+
Cygwin on x86 & (MRI) Ruby 1.8.7 & GMP 4.3.1 \\ \hline
|
147
|
+
Linux (LinuxMint 7) on x86 & (MRI) Ruby 1.8.7 & GMP 4.3.1 \\ \hline
|
148
|
+
Mac OS X 10.5.7 on x86 (32-bit) & (MRI) Ruby 1.8.6 & GMP 4.3.1 \\ \hline
|
149
|
+
Mac OS X 10.5.7 on x86 (32-bit) & (MRI) Ruby 1.9.1 & GMP 4.3.1 \\ \hline
|
150
|
+
Windows XP on x86 (32-bit) & (MRI) Ruby 1.9.1 & GMP 5.0.1 \\ \hline
|
151
|
+
\end{tabular}
|
152
|
+
|
153
|
+
\subsection{Installing}
|
154
|
+
You may clone the gmp gem's git repository with:\\
|
155
|
+
\\
|
156
|
+
\texttt{git clone git://github.com/srawlins/gmp.git}\\
|
157
|
+
|
158
|
+
Or you may install the gem from gemcutter:\\
|
159
|
+
\\
|
160
|
+
\texttt{gem install gmp}\\
|
161
|
+
|
162
|
+
Or you may install the gem from github (old):\\
|
163
|
+
\\
|
164
|
+
\texttt{gem install srawlins-gmp}\\
|
165
|
+
|
166
|
+
At this time, the gem does not self-compile (how does that work?). To compile the C
|
167
|
+
extensions, do the following:\\
|
168
|
+
\\
|
169
|
+
\texttt{cd <gmp gem directory>/ext}\\
|
170
|
+
\texttt{ruby extconf.rb}\\
|
171
|
+
\texttt{make}\\
|
172
|
+
|
173
|
+
There shouldn't be any errors, or warnings.
|
174
|
+
|
175
|
+
\section{Testing the gmp gem}
|
176
|
+
|
177
|
+
Testing the gmp gem is quite simple. The test/unit\_tests.rb suite uses Unit::Test.
|
178
|
+
You can run this test suite with:\\
|
179
|
+
\\
|
180
|
+
\texttt{cd <gmp gem directory>/test}\\
|
181
|
+
\texttt{ruby unit\_tests.rb}\\
|
182
|
+
|
183
|
+
All tests should pass. If you don't have the test-unit gem installed, then you may
|
184
|
+
run into one error. I'm not sure why this is... I suspect a bug in Ruby's Test::Unit
|
185
|
+
that the test-unit gem monkey patches.
|
186
|
+
|
187
|
+
\section{GMP and gmp gem basics}
|
188
|
+
|
189
|
+
\subsection{Classes}
|
190
|
+
The gmp gem includes the namespace \texttt{GMP} and four classes within \texttt{GMP}:
|
191
|
+
\begin{itemize}
|
192
|
+
\item \texttt{GMP::Z} - Methods for signed integer arithmetic. There are at least 45
|
193
|
+
methods here (still accounting).
|
194
|
+
\item \texttt{GMP::Q} - Methods for rational number arithmetic. There are at least 11
|
195
|
+
methods here (still accounting).
|
196
|
+
\item \texttt{GMP::F} - Methods for floating-point arithmetic. There are at least 6
|
197
|
+
methods here (still accounting).
|
198
|
+
\item \texttt{GMP::RandState} - Methods for random number generation. There are 3
|
199
|
+
methods here.
|
200
|
+
\end{itemize}
|
201
|
+
|
202
|
+
In addition to the above four classes, there is also one constant within \texttt{GMP}:
|
203
|
+
\begin{itemize}
|
204
|
+
\item \texttt{GMP::GMP\_VERSION} - The version of GMP compiled into the gmp gem.
|
205
|
+
\end{itemize}
|
206
|
+
|
207
|
+
\newpage
|
208
|
+
\section{Integer Functions}
|
209
|
+
|
210
|
+
\subsection{Initializing, Assigning Integers}
|
211
|
+
|
212
|
+
\begin{tabular}{p{\methwidth} l r}
|
213
|
+
\toprule
|
214
|
+
\textbf{new} & & GMP::Z.new $\rightarrow$ \textit{integer} \\
|
215
|
+
& & GMP::Z.new(\textit{numeric = 0}) $\rightarrow$ \textit{integer} \\
|
216
|
+
& & GMP::Z.new(\textit{str}) $\rightarrow$ \textit{integer} \\
|
217
|
+
\cmidrule(r){2-3}
|
218
|
+
& \multicolumn{2}{p{\defnwidth}}{
|
219
|
+
This method creates a new \textit{GMP::Z} integer. It takes one optional argument for
|
220
|
+
the value of the integer. This argument can be one of several classes. Here are some
|
221
|
+
examples:\newline
|
222
|
+
|
223
|
+
\texttt{GMP::Z.new \qqqquad\qqqquad \#=> 0 (default) \newline
|
224
|
+
GMP::Z.new(1) \qqqquad\qquad\ \#=> 1 (Ruby Fixnum) \newline
|
225
|
+
GMP::Z.new("127") \qqqquad\ \#=> 127 (Ruby String)\newline
|
226
|
+
GMP::Z.new(4294967296) \qquad \#=> 4294967296 (Ruby Bignum)\newline
|
227
|
+
GMP::Z.new(GMP::Z.new(31)) \#=> 31 (GMP Integer)}
|
228
|
+
}
|
229
|
+
\end{tabular}
|
230
|
+
\newline\newline
|
231
|
+
|
232
|
+
There is also a convenience method available, \texttt{GMP::Z()}.\\
|
233
|
+
|
234
|
+
\subsection{Converting Integers}
|
235
|
+
|
236
|
+
\begin{tabular}{p{\methwidth} l r}
|
237
|
+
\toprule
|
238
|
+
\textbf{to\_d} & & \textit{integer}.to\_d $\rightarrow$ \textit{float} \\
|
239
|
+
\cmidrule(r){2-3}
|
240
|
+
& \multicolumn{2}{p{\defnwidth}}{
|
241
|
+
Returns \textit{integer} as an Float if \textit{integer} fits in a Float.
|
242
|
+
|
243
|
+
Otherwise returns the least significant part of \texttt{integer}, with the same sign as
|
244
|
+
\textit{integer}.
|
245
|
+
|
246
|
+
If \textit{integer} is too big to fit in a Float, the returned result is probably not
|
247
|
+
very useful. To find out if the value will fit, use the function
|
248
|
+
\textit{mpz\_fits\_slong\_p} (\textbf{Unimplemented}).
|
249
|
+
}
|
250
|
+
\end{tabular}
|
251
|
+
\newline\newline
|
252
|
+
|
253
|
+
\begin{tabular}{p{\methwidth} l r}
|
254
|
+
\toprule
|
255
|
+
\textbf{to\_i} & & \textit{integer}.to\_i $\rightarrow$ \textit{fixnum} \\
|
256
|
+
\cmidrule(r){2-3}
|
257
|
+
& \multicolumn{2}{p{\defnwidth}}{
|
258
|
+
Returns \textit{integer} as a Fixnum if \textit{integer} fits in a Fixnum.
|
259
|
+
\newline
|
260
|
+
|
261
|
+
Otherwise returns the least significant part of \textit{integer}, with the same sign as
|
262
|
+
\textit{integer}.
|
263
|
+
\newline
|
264
|
+
|
265
|
+
If \textit{integer} is too big to fit in a Fixnum, the returned result is probably not
|
266
|
+
very useful. To find out if the value will fit, use the function
|
267
|
+
\textit{mpz\_fits\_slong\_p} (\textbf{Unimplemented}).
|
268
|
+
}
|
269
|
+
\end{tabular}
|
270
|
+
\newline\newline
|
271
|
+
|
272
|
+
\begin{tabular}{p{\methwidth} l r}
|
273
|
+
\toprule
|
274
|
+
\textbf{to\_s} & & \textit{integer}.to\_s(\textit{base = 10}) $\rightarrow$ \textit{str} \\
|
275
|
+
\cmidrule(r){2-3}
|
276
|
+
& \multicolumn{2}{p{\defnwidth}}{
|
277
|
+
Converts \textit{integer} to a string of digits in base \textit{base}. The
|
278
|
+
\textit{base} argument may vary from 2 to 62 or from -2 to -36, or be a symbol, one of
|
279
|
+
\textit{:bin}, \textit{:oct}, \textit{:dec}, or \textit{:hex}.
|
280
|
+
\newline
|
281
|
+
|
282
|
+
For \textit{base} in the range 2..36, digits and lower-case letters are used; for
|
283
|
+
-2..-36 (and \textit{:bin}, \textit{:oct}, \textit{:dec}, and \textit{:hex}), digits
|
284
|
+
and upper-case letters are used; for 37..62, digits, upper-case letters, and lower-case
|
285
|
+
letters (in that significance order) are used. Here are some
|
286
|
+
examples:\newline
|
287
|
+
|
288
|
+
\texttt{GMP::Z(1).to\_s \qqqquad \#=> "1" \newline
|
289
|
+
GMP::Z(32).to\_s(2) \qquad \#=> "100000" \newline
|
290
|
+
GMP::Z(32).to\_s(4) \qquad \#=> "200" \newline
|
291
|
+
GMP::Z(10).to\_s(16) \quad\ \#=> "a" \newline
|
292
|
+
GMP::Z(10).to\_s(-16) \quad \#=> "A" \newline
|
293
|
+
GMP::Z(255).to\_s(:bin) \#=> "11111111" \newline
|
294
|
+
GMP::Z(255).to\_s(:oct) \#=> "377" \newline
|
295
|
+
GMP::Z(255).to\_s(:dec) \#=> "255" \newline
|
296
|
+
GMP::Z(255).to\_s(:hex) \#=> "ff"}
|
297
|
+
}
|
298
|
+
\end{tabular}
|
299
|
+
|
300
|
+
\subsection{Integer Arithmetic}
|
301
|
+
|
302
|
+
\begin{tabular}{p{\methwidth} l r}
|
303
|
+
\toprule
|
304
|
+
\textbf{+} & & \textit{integer} + \textit{numeric} $\rightarrow$ \textit{numeric} \\
|
305
|
+
\cmidrule(r){2-3}
|
306
|
+
& \multicolumn{2}{p{\defnwidth}}{
|
307
|
+
Returns the sum of \textit{integer} and \textit{numeric}. \textit{numeric} can be an
|
308
|
+
instance of \textit{GMP::Z}, \textit{Fixnum}, \textit{GMP::Q}, \textit{GMP::F}, or
|
309
|
+
\textit{Bignum}.
|
310
|
+
}
|
311
|
+
\end{tabular}
|
312
|
+
\newline\newline
|
313
|
+
|
314
|
+
\begin{tabular}{p{\methwidth} l r}
|
315
|
+
\toprule
|
316
|
+
\textbf{add!} & & \textit{integer}.add!(\textit{numeric}) $\rightarrow$
|
317
|
+
\textit{numeric} \\
|
318
|
+
\cmidrule(r){2-3}
|
319
|
+
& \multicolumn{2}{p{\defnwidth}}{
|
320
|
+
Sums \textit{integer} and \textit{numeric}, in place. \textit{numeric} can be an
|
321
|
+
instance of \textit{GMP::Z}, \textit{Fixnum}, \textit{GMP::Q}, \textit{GMP::F}, or
|
322
|
+
\textit{Bignum}.
|
323
|
+
}
|
324
|
+
\end{tabular}
|
325
|
+
\newline\newline
|
326
|
+
|
327
|
+
\begin{tabular}{p{\methwidth} l r}
|
328
|
+
\toprule
|
329
|
+
\textbf{-} & & \textit{integer} - \textit{numeric} $\rightarrow$ \textit{numeric} \\
|
330
|
+
& & \textit{integer}.sub!(\textit{numeric}) $\rightarrow$ \textit{numeric} \\
|
331
|
+
\cmidrule(r){2-3}
|
332
|
+
& \multicolumn{2}{p{\defnwidth}}{
|
333
|
+
Returns the difference of \textit{integer} and \textit{numeric}. The destructive method
|
334
|
+
calculates the difference in place. \textit{numeric} can be an instance of
|
335
|
+
\textit{GMP::Z}, \textit{Fixnum}, \textit{GMP::Q}, \textit{GMP::F}, or \textit{Bignum}.
|
336
|
+
Here are some examples:\newline
|
337
|
+
|
338
|
+
\texttt{seven = GMP::Z(7) \newline
|
339
|
+
nine \ = GMP::Z(9) \newline
|
340
|
+
half \ = GMP::Q(1,2) \newline
|
341
|
+
pi \quad\ = GMP::F("3.14") \newline
|
342
|
+
nine - 5 \qquad\quad \#=> 4 (GMP Integer) \newline
|
343
|
+
nine - seven \quad \#=> 2 (GMP Integer) \newline
|
344
|
+
nine - (2**32) \#=> -4294967287 (GMP Integer) \newline
|
345
|
+
nine - nine \quad\ \#=> 0 (GMP Integer) \newline
|
346
|
+
nine - half \quad\ \#=> 8.5 (GMP Rational) \newline
|
347
|
+
nine - pi \qquad\ \#=> 5.86 (GMP Float)}
|
348
|
+
|
349
|
+
}
|
350
|
+
\end{tabular}
|
351
|
+
\newline\newline
|
352
|
+
|
353
|
+
\begin{tabular}{p{\methwidth} l r}
|
354
|
+
\toprule
|
355
|
+
\textbf{*} & & \textit{integer} * \textit{numeric} $\rightarrow$ \textit{numeric} \\
|
356
|
+
& & \textit{integer}.mul(\textit{numeric}) $\rightarrow$ \textit{numeric} \\
|
357
|
+
& & \textit{integer}.mul!(\textit{numeric}) $\rightarrow$ \textit{numeric} \\
|
358
|
+
\cmidrule(r){2-3}
|
359
|
+
& \multicolumn{2}{p{\defnwidth}}{
|
360
|
+
Returns the product of \textit{integer} and \textit{numeric}. The destructive method
|
361
|
+
calculates the product in place. \textit{numeric} can be an instance of
|
362
|
+
\textit{GMP::Z}, \textit{Fixnum}, \textit{GMP::Q}, \textit{GMP::F}, or \textit{Bignum}.
|
363
|
+
}
|
364
|
+
\end{tabular}
|
365
|
+
\newline\newline
|
366
|
+
|
367
|
+
\begin{tabular}{p{\methwidth} l r}
|
368
|
+
\toprule
|
369
|
+
\textbf{\textless\textless} & & \textit{integer} \textless\textless \textit{numeric} $\rightarrow$ \textit{integer} \\
|
370
|
+
\cmidrule(r){2-3}
|
371
|
+
& \multicolumn{2}{p{\defnwidth}}{
|
372
|
+
Returns \textit{integer} times 2 to the \textit{numeric} power. This can also be
|
373
|
+
defined as a left shift by \textit{numeric} bits.
|
374
|
+
}
|
375
|
+
\end{tabular}
|
376
|
+
\newline\newline
|
377
|
+
|
378
|
+
\begin{tabular}{p{\methwidth} l r}
|
379
|
+
\toprule
|
380
|
+
\textbf{-@} & & -\textit{integer}\\
|
381
|
+
& & \textit{integer}.neg\\
|
382
|
+
& & \textit{integer}.neg!\\
|
383
|
+
\cmidrule(r){2-3}
|
384
|
+
& \multicolumn{2}{p{\defnwidth}}{
|
385
|
+
Returns the negation, the additive inverse, of \textit{integer}. The destructive method
|
386
|
+
negates in place.
|
387
|
+
}
|
388
|
+
\end{tabular}
|
389
|
+
\newline\newline
|
390
|
+
|
391
|
+
\begin{tabular}{p{\methwidth} l r}
|
392
|
+
\toprule
|
393
|
+
\textbf{abs} & & \textit{integer}.abs\\
|
394
|
+
& & \textit{integer}.abs!\\
|
395
|
+
\cmidrule(r){2-3}
|
396
|
+
& \multicolumn{2}{p{\defnwidth}}{
|
397
|
+
Returns the absolute value of \textit{integer}. The destructive method calculates the
|
398
|
+
absolute value in place.
|
399
|
+
}
|
400
|
+
\end{tabular}
|
401
|
+
|
402
|
+
\subsection{Integer Division}
|
403
|
+
|
404
|
+
\begin{tabular}{p{\methwidth} l r}
|
405
|
+
\toprule
|
406
|
+
\textbf{tdiv} & & $integer$.tdiv($numeric$) $\rightarrow$ $integer$\\
|
407
|
+
\cmidrule(r){2-3}
|
408
|
+
& \multicolumn{2}{p{\defnwidth}}{
|
409
|
+
Returns the division of $integer$ by $numeric$, truncated. $numeric$ can be an instance
|
410
|
+
of $GMP::Z$, $Fixnum$, $Bignum$. The return object's class is always $GMP::Z$.
|
411
|
+
}
|
412
|
+
\end{tabular}
|
413
|
+
\newline\newline
|
414
|
+
|
415
|
+
\begin{tabular}{p{\methwidth} l r}
|
416
|
+
\toprule
|
417
|
+
\textbf{fdiv} & & $integer$.fdiv($numeric$) $\rightarrow$ $integer$\\
|
418
|
+
\cmidrule(r){2-3}
|
419
|
+
& \multicolumn{2}{p{\defnwidth}}{
|
420
|
+
Returns the division of $integer$ by $numeric$, floored. $numeric$ can be an instance
|
421
|
+
of $GMP::Z$, $Fixnum$, $Bignum$. The return object's class is always $GMP::Z$.
|
422
|
+
}
|
423
|
+
\end{tabular}
|
424
|
+
\newline\newline
|
425
|
+
|
426
|
+
\begin{tabular}{p{\methwidth} l r}
|
427
|
+
\toprule
|
428
|
+
\textbf{cdiv} & & $integer$.cdiv($numeric$) $\rightarrow$ $integer$\\
|
429
|
+
\cmidrule(r){2-3}
|
430
|
+
& \multicolumn{2}{p{\defnwidth}}{
|
431
|
+
Returns the ceiling division of $integer$ by $numeric$. $numeric$ can be an instance of
|
432
|
+
$GMP::Z$, $Fixnum$, $Bignum$. The return object's class is always $GMP::Z$.
|
433
|
+
}
|
434
|
+
\end{tabular}
|
435
|
+
\newline\newline
|
436
|
+
|
437
|
+
\begin{tabular}{p{\methwidth} l r}
|
438
|
+
\toprule
|
439
|
+
\textbf{tmod} & & $integer$.tmod($numeric$) $\rightarrow$ $integer$\\
|
440
|
+
\cmidrule(r){2-3}
|
441
|
+
& \multicolumn{2}{p{\defnwidth}}{
|
442
|
+
Returns the remainder after truncated division of $integer$ by $numeric$. $numeric$ can
|
443
|
+
be an instance of $GMP::Z$, $Fixnum$, or $Bignum$. The return object's class is always
|
444
|
+
$GMP::Z$.
|
445
|
+
}
|
446
|
+
\end{tabular}
|
447
|
+
\newline\newline
|
448
|
+
|
449
|
+
\begin{tabular}{p{\methwidth} l r}
|
450
|
+
\toprule
|
451
|
+
\textbf{fmod} & & $integer$.fmod($numeric$) $\rightarrow$ $integer$\\
|
452
|
+
\cmidrule(r){2-3}
|
453
|
+
& \multicolumn{2}{p{\defnwidth}}{
|
454
|
+
Returns the remainder after floored division of $integer$ by $numeric$. $numeric$ can
|
455
|
+
be an instance of $GMP::Z$, $Fixnum$, or $Bignum$. The return object's class is always
|
456
|
+
$GMP::Z$.
|
457
|
+
}
|
458
|
+
\end{tabular}
|
459
|
+
\newline\newline
|
460
|
+
|
461
|
+
\begin{tabular}{p{\methwidth} l r}
|
462
|
+
\toprule
|
463
|
+
\textbf{cmod} & & \textit{integer}.cmod(\textit{numeric}) $\rightarrow$ \textit{integer}\\
|
464
|
+
\cmidrule(r){2-3}
|
465
|
+
& \multicolumn{2}{p{\defnwidth}}{
|
466
|
+
Returns the remainder after ceilinged division of $integer$ by $numeric$. $numeric$ can
|
467
|
+
be an instance of $GMP::Z$, $Fixnum$, or $Bignum$. The return object's class is always
|
468
|
+
$GMP::Z$.
|
469
|
+
}
|
470
|
+
\end{tabular}
|
471
|
+
\newline\newline
|
472
|
+
|
473
|
+
\begin{tabular}{p{\methwidth} l r}
|
474
|
+
\toprule
|
475
|
+
\textbf{\%} & & \textit{integer} \% \textit{numeric} $\rightarrow$ \textit{integer}\\
|
476
|
+
\cmidrule(r){2-3}
|
477
|
+
& \multicolumn{2}{p{\defnwidth}}{
|
478
|
+
Returns $integer$ modulo $numeric$. $numeric$ can be an instance of \gmpz, $Fixnum$,
|
479
|
+
or $Bignum$. The return object's class is always \gmpz.
|
480
|
+
}
|
481
|
+
\end{tabular}
|
482
|
+
|
483
|
+
\subsection{Integer Roots}
|
484
|
+
|
485
|
+
\begin{tabular}{p{\methwidth} l r}
|
486
|
+
\toprule
|
487
|
+
\textbf{root} & & \textit{integer}.root(\textit{numeric}) $\rightarrow$ \textit{numeric} \\
|
488
|
+
\cmidrule(r){2-3}
|
489
|
+
& \multicolumn{2}{p{\defnwidth}}{
|
490
|
+
Returns the integer part of the $numeric$'th root of $integer$.
|
491
|
+
}
|
492
|
+
\end{tabular}
|
493
|
+
\newline\newline
|
494
|
+
|
495
|
+
\begin{tabular}{p{\methwidth} l r}
|
496
|
+
\toprule
|
497
|
+
\textbf{sqrt} & & \textit{integer}.sqrt $\rightarrow$ \textit{numeric} \\
|
498
|
+
& & \textit{integer}.sqrt!(\textit{numeric}) $\rightarrow$ \textit{numeric} \\
|
499
|
+
\cmidrule(r){2-3}
|
500
|
+
& \multicolumn{2}{p{\defnwidth}}{
|
501
|
+
Returns the truncated integer part of the square root of $integer$.
|
502
|
+
}
|
503
|
+
\end{tabular}
|
504
|
+
\newline\newline
|
505
|
+
|
506
|
+
\begin{tabular}{p{\methwidth} l r}
|
507
|
+
\toprule
|
508
|
+
\textbf{sqrtrem} & & \textit{integer}.sqrtrem $\rightarrow$ \textit{sqrt}, \textit{rem} \\
|
509
|
+
\cmidrule(r){2-3}
|
510
|
+
& \multicolumn{2}{p{\defnwidth}}{
|
511
|
+
Returns the truncated integer part of the square root of $integer$ as $sqrt$ and the
|
512
|
+
remainder, $integer - sqrt * sqrt$, as $rem$, which will be zero if $integer$ is a
|
513
|
+
perfect square.
|
514
|
+
}
|
515
|
+
\end{tabular}
|
516
|
+
\newline\newline
|
517
|
+
|
518
|
+
\begin{tabular}{p{\methwidth} l r}
|
519
|
+
\toprule
|
520
|
+
\textbf{power?} & & \textit{integer}.power? $\rightarrow$ \textit{true} \textbar\ \textit{false} \\
|
521
|
+
\cmidrule(r){2-3}
|
522
|
+
& \multicolumn{2}{p{\defnwidth}}{
|
523
|
+
Returns true if $integer$ is a perfect power, i.e., if there exist integers $a$ and
|
524
|
+
$b$, with $b > 1$, such that $integer$ equals $a$ raised to the power $b$.
|
525
|
+
\newline\newline
|
526
|
+
Under this definition both 0 and 1 are considered to be perfect powers. Negative values
|
527
|
+
of integers are accepted, but of course can only be odd perfect powers.
|
528
|
+
}
|
529
|
+
\end{tabular}
|
530
|
+
\newline\newline
|
531
|
+
|
532
|
+
\begin{tabular}{p{\methwidth} l r}
|
533
|
+
\toprule
|
534
|
+
\textbf{square?} & & \textit{integer}.square? $\rightarrow$ \textit{true} \textbar\ \textit{false} \\
|
535
|
+
\cmidrule(r){2-3}
|
536
|
+
& \multicolumn{2}{p{\defnwidth}}{
|
537
|
+
Returns true if $integer$ is a perfect square, i.e., if the square root of
|
538
|
+
$integer$ is an integer. Under this definition both 0 and 1 are considered to be
|
539
|
+
perfect squares.
|
540
|
+
}
|
541
|
+
\end{tabular}
|
542
|
+
|
543
|
+
\subsection{Integer Exponentiation}
|
544
|
+
|
545
|
+
\begin{tabular}{p{\methwidth} l r}
|
546
|
+
\toprule
|
547
|
+
\textbf{**} & & \textit{integer} ** \textit{numeric} $\rightarrow$ \textit{numeric} \\
|
548
|
+
& & \textit{integer}.pow(\textit{numeric}) $\rightarrow$ \textit{numeric} \\
|
549
|
+
\cmidrule(r){2-3}
|
550
|
+
& \multicolumn{2}{p{\defnwidth}}{
|
551
|
+
Returns $integer$ raised to the $numeric$ power.
|
552
|
+
}
|
553
|
+
\end{tabular}
|
554
|
+
\newline\newline
|
555
|
+
|
556
|
+
\begin{tabular}{p{\methwidth} l r}
|
557
|
+
\toprule
|
558
|
+
\textbf{powmod} & & \textit{integer}.powmod(\textit{exp}, \textit{mod}) $\rightarrow$ \textit{integer} \\
|
559
|
+
\cmidrule(r){2-3}
|
560
|
+
& \multicolumn{2}{p{\defnwidth}}{
|
561
|
+
Returns $integer$ raised to the $exp$ power, modulo $mod$. Negative $exp$ is supported
|
562
|
+
if an inverse, $integer^{-1}$ modulo $mod$, exists. If an inverse doesn't exist then a
|
563
|
+
divide by zero exception is raised.
|
564
|
+
}
|
565
|
+
\end{tabular}
|
566
|
+
|
567
|
+
\subsection{Number Theoretic Functions}
|
568
|
+
|
569
|
+
\begin{tabular}{p{\methwidth} l r}
|
570
|
+
\toprule
|
571
|
+
\textbf{is\_probab\_prime?} & & $integer$.is\_probab\_prime?($reps = 5$) $\rightarrow$ 0, 1, or 2 \\
|
572
|
+
\cmidrule(r){2-3}
|
573
|
+
& \multicolumn{2}{p{\defnwidth}}{
|
574
|
+
Determine whether $integer$ is prime. Returns 2 if $integer$ is definitely prime,
|
575
|
+
returns 1 if $integer$ is probably prime (without being certain), or returns 0 if
|
576
|
+
$integer$ is definitely composite.
|
577
|
+
\newline\newline
|
578
|
+
This function does some trial divisions, then some Miller-Rabin probabilistic primality
|
579
|
+
tests. $reps$ controls how many such tests are done, 5 to 10 is a reasonable number,
|
580
|
+
more will reduce the chances of a composite being returned as �probably prime�.
|
581
|
+
\newline\newline
|
582
|
+
Miller-Rabin and similar tests can be more properly called compositeness tests. Numbers
|
583
|
+
which fail are known to be composite but those which pass might be prime or might be
|
584
|
+
composite. Only a few composites pass, hence those which pass are considered probably
|
585
|
+
prime.
|
586
|
+
}
|
587
|
+
\end{tabular}
|
588
|
+
\newline\newline
|
589
|
+
|
590
|
+
\begin{tabular}{p{\methwidth} l r}
|
591
|
+
\toprule
|
592
|
+
\textbf{next\_prime} & & $integer$.next\_prime $\rightarrow$ $prime$ \\
|
593
|
+
& & $integer$.nextprime $\rightarrow$ $prime$ \\
|
594
|
+
& & $integer$.next\_prime! $\rightarrow$ $prime$ \\
|
595
|
+
& & $integer$.nextprime! $\rightarrow$ $prime$ \\
|
596
|
+
\cmidrule(r){2-3}
|
597
|
+
& \multicolumn{2}{p{\defnwidth}}{
|
598
|
+
Returns the next prime greater than $integer$. The destructive method sets $integer$ to
|
599
|
+
the next prime greater than $integer$.
|
600
|
+
\newline\newline
|
601
|
+
This function uses a probabilistic algorithm to identify primes. For practical purposes
|
602
|
+
it's adequate, the chance of a composite passing will be extremely small.
|
603
|
+
}
|
604
|
+
\end{tabular}
|
605
|
+
\newline\newline
|
606
|
+
|
607
|
+
\begin{tabular}{p{\methwidth} l r}
|
608
|
+
\toprule
|
609
|
+
\textbf{gcd} & & $a$.gcd($b$) $\rightarrow$ $g$ \\
|
610
|
+
\cmidrule(r){2-3}
|
611
|
+
& \multicolumn{2}{p{\defnwidth}}{
|
612
|
+
Computes the greatest common divisor of $a$ and $b$. $g$ will always be positive, even
|
613
|
+
if $a$ or $b$ is negative. $b$ can be an instance of \gmpz, $Fixnum$, or $Bignum$.
|
614
|
+
\newline\newline
|
615
|
+
\texttt{GMP::Z(24).gcd(GMP::Z(8)) \quad \#=> GMP::Z(8) \newline
|
616
|
+
GMP::Z(24).gcd(8) \quad \#=> GMP::Z(8) \newline
|
617
|
+
GMP::Z(24).gcd(2**32) \quad \#=> GMP::Z(8)}
|
618
|
+
}
|
619
|
+
\end{tabular}
|
620
|
+
\newline\newline
|
621
|
+
|
622
|
+
\begin{tabular}{p{\methwidth} l r}
|
623
|
+
\toprule
|
624
|
+
\textbf{invert} & & $a$.invert($m$) $\rightarrow$ $integer$ \\
|
625
|
+
\cmidrule(r){2-3}
|
626
|
+
& \multicolumn{2}{p{\defnwidth}}{
|
627
|
+
Computes the inverse of $a$ mod $m$. $m$ can be an instance of \gmpz, $Fixnum$, or
|
628
|
+
$Bignum$.
|
629
|
+
\newline\newline
|
630
|
+
\texttt{GMP::Z(2).invert(GMP::Z(11)) \quad \#=> GMP::Z(6) \newline
|
631
|
+
GMP::Z(3).invert(11) \quad \#=> GMP::Z(4) \newline
|
632
|
+
GMP::Z(5).invert(11) \quad \#=> GMP::Z(9)}
|
633
|
+
}
|
634
|
+
\end{tabular}
|
635
|
+
\newline\newline
|
636
|
+
|
637
|
+
\begin{tabular}{p{\methwidth} l r}
|
638
|
+
\toprule
|
639
|
+
\textbf{jacobi} & & $a$.jacobi($b$) $\rightarrow$ $integer$ \\
|
640
|
+
& & GMP::Z.jacobi($a$, $b$) $\rightarrow$ $integer$ \\
|
641
|
+
\cmidrule(r){2-3}
|
642
|
+
& \multicolumn{2}{p{\defnwidth}}{
|
643
|
+
Returns the Jacobi symbol $(a/b)$. This is defined only for $b$ odd. If $b$ is even, a
|
644
|
+
range exception will be raised.
|
645
|
+
\newline\newline
|
646
|
+
\textit{GMP::Z.jacobi} (the instance method) requires $b$ to be an instance of \gmpz.
|
647
|
+
\newline
|
648
|
+
\textit{GMP::Z\#jacobi} (the class method) requires $a$ and $b$ each to be an instance of
|
649
|
+
\gmpz, $Fixnum$, or $Bignum$.
|
650
|
+
}
|
651
|
+
\end{tabular}
|
652
|
+
\newline\newline
|
653
|
+
|
654
|
+
\begin{tabular}{p{\methwidth} l r}
|
655
|
+
\toprule
|
656
|
+
\textbf{legendre} & & $a$.legendre($b$) $\rightarrow$ $integer$ \\
|
657
|
+
\cmidrule(r){2-3}
|
658
|
+
& \multicolumn{2}{p{\defnwidth}}{
|
659
|
+
Returns the Legendre symbol $(a/b)$. This is defined only for $p$ an odd positive
|
660
|
+
prime. If $p$ is even, negative, or composite, a range exception will be raised.
|
661
|
+
}
|
662
|
+
\end{tabular}
|
663
|
+
\newline\newline
|
664
|
+
|
665
|
+
\begin{tabular}{p{\methwidth} l r}
|
666
|
+
\toprule
|
667
|
+
\textbf{remove} & & $n$.remove($factor$) $\rightarrow$ ($integer$, $times$) \\
|
668
|
+
\cmidrule(r){2-3}
|
669
|
+
& \multicolumn{2}{p{\defnwidth}}{
|
670
|
+
Remove all occurrences of the factor $factor$ from $n$. $factor$ can be an instance of
|
671
|
+
\gmpz, $Fixnum$, or $Bignum$. $integer$ is the resulting integer, an instance of
|
672
|
+
\gmpz. $times$ is how many times $factor$ was removed, a $Fixnum$.
|
673
|
+
}
|
674
|
+
\end{tabular}
|
675
|
+
\newline\newline
|
676
|
+
|
677
|
+
\begin{tabular}{p{\methwidth} l r}
|
678
|
+
\toprule
|
679
|
+
\textbf{fac} & & GMP::Z.fac($n$) $\rightarrow$ $integer$ \\
|
680
|
+
\cmidrule(r){2-3}
|
681
|
+
& \multicolumn{2}{p{\defnwidth}}{
|
682
|
+
Returns $n!$, or, $n$ factorial.
|
683
|
+
}
|
684
|
+
\end{tabular}
|
685
|
+
\newline\newline
|
686
|
+
|
687
|
+
\begin{tabular}{p{\methwidth} l r}
|
688
|
+
\toprule
|
689
|
+
\textbf{fib} & & GMP::Z.fib($n$) $\rightarrow$ $integer$ \\
|
690
|
+
\cmidrule(r){2-3}
|
691
|
+
& \multicolumn{2}{p{\defnwidth}}{
|
692
|
+
Returns $F[n]$, or, the $n$th Fibonacci number.
|
693
|
+
}
|
694
|
+
\end{tabular}
|
695
|
+
|
696
|
+
|
697
|
+
|
698
|
+
\subsection{Integer Logic and Bit Fiddling}
|
699
|
+
|
700
|
+
\begin{tabular}{p{\methwidth} l r}
|
701
|
+
\toprule
|
702
|
+
\textbf{and} & & $a$ \& $b$ $\rightarrow$ $integer$ \\
|
703
|
+
\cmidrule(r){2-3}
|
704
|
+
& \multicolumn{2}{p{\defnwidth}}{
|
705
|
+
Returns $integer$, the bitwise and of $a$ and $b$.
|
706
|
+
}
|
707
|
+
\end{tabular}
|
708
|
+
\newline\newline
|
709
|
+
|
710
|
+
\begin{tabular}{p{\methwidth} l r}
|
711
|
+
\toprule
|
712
|
+
\textbf{ior} & & $a$ \textbar\ $b$ $\rightarrow$ $integer$ \\
|
713
|
+
\cmidrule(r){2-3}
|
714
|
+
& \multicolumn{2}{p{\defnwidth}}{
|
715
|
+
Returns $integer$, the bitwise inclusive or of $a$ and $b$.
|
716
|
+
}
|
717
|
+
\end{tabular}
|
718
|
+
\newline\newline
|
719
|
+
|
720
|
+
\begin{tabular}{p{\methwidth} l r}
|
721
|
+
\toprule
|
722
|
+
\textbf{xor} & & $a$ \textasciicircum\ $b$ $\rightarrow$ $integer$ \\
|
723
|
+
\cmidrule(r){2-3}
|
724
|
+
& \multicolumn{2}{p{\defnwidth}}{
|
725
|
+
Returns $integer$, the bitwise exclusive or of $a$ and $b$.
|
726
|
+
}
|
727
|
+
\end{tabular}
|
728
|
+
\newline\newline
|
729
|
+
|
730
|
+
\begin{tabular}{p{\methwidth} l r}
|
731
|
+
\toprule
|
732
|
+
\textbf{scan0} & & $n$.scan0($i$) $\rightarrow$ $integer$ \\
|
733
|
+
\cmidrule(r){2-3}
|
734
|
+
& \multicolumn{2}{p{\defnwidth}}{
|
735
|
+
Scans $n$, starting from bit $i$, towards more significant bits, until the first 0 bit
|
736
|
+
is found. Return the index of the found bit.
|
737
|
+
\newline\newline
|
738
|
+
If the bit at $i$ is already what's sought, then $i$ is returned.
|
739
|
+
\newline\newline
|
740
|
+
If there's no bit found, then $INT2FIX(ULONG\_MAX)$ is returned. This will happen in
|
741
|
+
scan0 past the end of a negative number.
|
742
|
+
}
|
743
|
+
\end{tabular}
|
744
|
+
|
745
|
+
\newpage
|
746
|
+
\section{Random Number Functions}
|
747
|
+
|
748
|
+
\subsection{Random State Initialization}
|
749
|
+
|
750
|
+
\begin{tabular}{p{\methwidth} l r}
|
751
|
+
\toprule
|
752
|
+
\textbf{new} & & GMP::RandState.new $\rightarrow$ \textit{mersenne twister state} \\
|
753
|
+
& & GMP::RandState.new(:default) $\rightarrow$ \textit{mersenne twister state} \\
|
754
|
+
& & GMP::RandState(:mt) $\rightarrow$ \textit{mersenne twister random state} \\
|
755
|
+
& & GMP::RandState.new(:lc\_2exp, a, c, m2exp) $\rightarrow$ \textit{linear congruential state} \\
|
756
|
+
& & GMP::RandState.new(:lc\_2exp\_size, size) $\rightarrow$ \textit{linear congruential state} \\
|
757
|
+
\cmidrule(r){2-3}
|
758
|
+
& \multicolumn{2}{p{\defnwidth}}{
|
759
|
+
This method creates a new \gmprandstate instance. The first argument defaults
|
760
|
+
to \textit{:default} (also \textit{:mt}), which initializes the \gmprandstate for a Mersenne
|
761
|
+
Twister algorithm. No other arguments should be given if \textit{:default} or \textit{:mt} is
|
762
|
+
specified.
|
763
|
+
\newline\newline
|
764
|
+
If the first argument given is \textit{:lc\_2exp}, then the \gmprandstate is
|
765
|
+
initialized for a linear congruential algorithm. \textit{:lc\_2exp} must be followed with $a$,
|
766
|
+
$c$, and $m2exp$. The algorithm can then proceed as ($X = (a*X + c) \mod 2^{m2exp}$).
|
767
|
+
\newline\newline
|
768
|
+
\gmprandstate can also be initialized for a linear congruential algorithm with
|
769
|
+
\textit{:lc\_2exp\_size}. This initializer instead takes just one argument, $size$. $a$, $c$,
|
770
|
+
and $m2exp$ are then chosen from a table, with $m2exp/2 > size$. The maximum size
|
771
|
+
currently supported is 128.\newline
|
772
|
+
|
773
|
+
\texttt{GMP::RandState.new \newline
|
774
|
+
GMP::RandState.new(:mt) \newline
|
775
|
+
GMP::RandState.new(:lc\_2exp, 1103515245, 12345, 15) \quad \#=> Perl's old rand() \newline
|
776
|
+
GMP::RandState.new(:lc\_2exp, 25\_214\_903\_917, 11, 48) \quad \#=> drand48}
|
777
|
+
}
|
778
|
+
\end{tabular}
|
779
|
+
|
780
|
+
\subsection{Random State Seeding}
|
781
|
+
|
782
|
+
\begin{tabular}{p{\methwidth} l r}
|
783
|
+
\toprule
|
784
|
+
\textbf{seed} & & $state$.seed($integer$) $\rightarrow$ $integer$ \\
|
785
|
+
\cmidrule(r){2-3}
|
786
|
+
& \multicolumn{2}{p{\defnwidth}}{
|
787
|
+
Set an initial seed value into $state$. $integer$ can be an instance of \gmpz,
|
788
|
+
$Fixnum$, or $Bignum$.
|
789
|
+
}
|
790
|
+
\end{tabular}
|
791
|
+
|
792
|
+
\subsection{Integer Random Numbers}
|
793
|
+
|
794
|
+
\begin{tabular}{p{\methwidth} l r}
|
795
|
+
\toprule
|
796
|
+
\textbf{urandomb} & & $state$.urandomb($n$) $\rightarrow$ $n$ \\
|
797
|
+
\cmidrule(r){2-3}
|
798
|
+
& \multicolumn{2}{p{\defnwidth}}{
|
799
|
+
Generates a uniformly distributed random integer in the range $0$ to $2^n -1$,
|
800
|
+
inclusive.
|
801
|
+
}
|
802
|
+
\end{tabular}
|
803
|
+
|
804
|
+
\end{document}
|