gmp 0.1.7
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +47 -0
- data/INSTALL +4 -0
- data/README.rdoc +257 -0
- data/ext/extconf.rb +30 -0
- data/ext/gmp.c +195 -0
- data/ext/gmpf.c +584 -0
- data/ext/gmpf.h +144 -0
- data/ext/gmpq.c +774 -0
- data/ext/gmpq.h +12 -0
- data/ext/gmpz.c +1774 -0
- data/ext/gmpz.h +20 -0
- data/ext/ruby_gmp.h +199 -0
- data/ext/takeover.h +36 -0
- data/manual.tex +183 -0
- data/test/README +41 -0
- data/test/tc_cmp.rb +74 -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_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_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_helper.rb +2 -0
- data/test/unit_tests.rb +135 -0
- metadata +89 -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/ruby_gmp.h
ADDED
@@ -0,0 +1,199 @@
|
|
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
|
+
#define mpz_get_struct(ruby_var,c_var) { Data_Get_Struct(ruby_var, MP_INT, c_var); }
|
38
|
+
#define mpq_get_struct(ruby_var,c_var) { Data_Get_Struct(ruby_var, MP_RAT, c_var); }
|
39
|
+
#define mpf_get_struct(ruby_var,c_var) { Data_Get_Struct(ruby_var, MP_FLOAT, c_var); }
|
40
|
+
#define mpf_get_struct_prec(ruby_var,c_var,prec) { mpf_get_struct(ruby_var,c_var); prec = mpf_get_prec(c_var); }
|
41
|
+
#define mpz_make_struct(ruby_var,c_var) { ruby_var = Data_Make_Struct(cGMP_Z, MP_INT, 0, r_gmpz_free, c_var); }
|
42
|
+
#define mpq_make_struct(ruby_var,c_var) { ruby_var = Data_Make_Struct(cGMP_Q, MP_RAT, 0, r_gmpq_free, c_var); }
|
43
|
+
#define mpf_make_struct(ruby_var,c_var) { ruby_var = Data_Make_Struct(cGMP_F, MP_FLOAT, 0, r_gmpf_free, c_var); }
|
44
|
+
#define mpz_make_struct_init(ruby_var,c_var) { mpz_make_struct(ruby_var,c_var); mpz_init (c_var); }
|
45
|
+
#define mpq_make_struct_init(ruby_var,c_var) { mpq_make_struct(ruby_var,c_var); mpq_init (c_var); }
|
46
|
+
#define mpf_make_struct_init(ruby_var,c_var,prec) { mpf_make_struct(ruby_var,c_var); mpf_init2 (c_var,prec); }
|
47
|
+
#define BIGNUM_P(value) (TYPE(value) == T_BIGNUM)
|
48
|
+
#define FLOAT_P(value) (TYPE(value) == T_FLOAT)
|
49
|
+
#define STRING_P(value) (TYPE(value) == T_STRING)
|
50
|
+
#define GMPZ_P(value) (rb_obj_is_instance_of(value, cGMP_Z) == Qtrue)
|
51
|
+
#define GMPQ_P(value) (rb_obj_is_instance_of(value, cGMP_Q) == Qtrue)
|
52
|
+
#define GMPF_P(value) (rb_obj_is_instance_of(value, cGMP_F) == Qtrue)
|
53
|
+
#define mpz_set_bignum(var_mpz,var_bignum) \
|
54
|
+
mpz_set_str (var_mpz, STR2CSTR (rb_funcall (var_bignum, rb_intern ("to_s"), 0)), 0);
|
55
|
+
#define mpz_temp_alloc(var) { var=malloc(sizeof(MP_INT)); }
|
56
|
+
#define mpz_temp_init(var) { mpz_temp_alloc(var); mpz_init(var); }
|
57
|
+
#define mpz_temp_from_bignum(var,var_bignum) \
|
58
|
+
{ mpz_temp_alloc(var); mpz_init_set_str(var, STR2CSTR(rb_funcall(var_bignum, rb_intern("to_s"), 0)), 0); }
|
59
|
+
#define mpz_temp_free(var) { mpz_clear(var); free(var); }
|
60
|
+
#define mpf_temp_alloc(var) { var=malloc(sizeof(MP_FLOAT)); }
|
61
|
+
#define mpf_temp_init(var,prec) { mpf_temp_alloc(var); mpf_init2(var,prec); }
|
62
|
+
#define mpf_temp_free(var) { mpf_clear(var); free(var); }
|
63
|
+
#define prec_max(prec,var) {if(mpf_get_prec(var) > prec) prec = mpf_get_prec(var); }
|
64
|
+
|
65
|
+
#define EXPECTED_ZQFXBD "Expected GMP::Z, GMP::Q, GMP::F, FixNum, BigNum or Float"
|
66
|
+
#define EXPECTED_ZQFXB "Expected GMP::Z, GMP::Q, GMP::F, FixNum or BigNum"
|
67
|
+
#define EXPECTED_ZXB "Expected GMP::Z, FixNum or BigNum"
|
68
|
+
#define EXPECTED_ZX "Expected GMP::Z or FixNum"
|
69
|
+
#define EXPECTED_X "Expected FixNum"
|
70
|
+
#define typeerror(expected) rb_raise(rb_eTypeError, EXPECTED_##expected)
|
71
|
+
#define typeerror_as(expected, argname) rb_raise(rb_eTypeError, EXPECTED_##expected " as " argname)
|
72
|
+
|
73
|
+
//should change exception type
|
74
|
+
#define not_yet rb_raise(rb_eTypeError,"Not implemented yet")
|
75
|
+
|
76
|
+
extern VALUE mGMP, cGMP_Z, cGMP_Q, cGMP_F;
|
77
|
+
|
78
|
+
extern void r_gmpz_free(void *ptr);
|
79
|
+
extern void r_gmpq_free(void *ptr);
|
80
|
+
extern void r_gmpf_free(void *ptr);
|
81
|
+
|
82
|
+
|
83
|
+
/* from gmpz.h */
|
84
|
+
|
85
|
+
// Initializing, Assigning Integers
|
86
|
+
extern VALUE r_gmpzsg_new(int argc, VALUE *argv, VALUE klass);
|
87
|
+
extern VALUE r_gmpz_initialize(int argc, VALUE *argv, VALUE self);
|
88
|
+
extern void mpz_set_value(MP_INT *target, VALUE source);
|
89
|
+
extern VALUE r_gmpmod_z(int argc, VALUE *argv, VALUE module);
|
90
|
+
extern VALUE r_gmpz_swap(VALUE self, VALUE arg);
|
91
|
+
|
92
|
+
// Converting Integers
|
93
|
+
extern VALUE r_gmpz_to_i(VALUE self);
|
94
|
+
extern VALUE r_gmpz_to_d(VALUE self);
|
95
|
+
extern VALUE r_gmpz_to_s(int argc, VALUE *argv, VALUE self);
|
96
|
+
|
97
|
+
// Integer Arithmetic
|
98
|
+
extern VALUE r_gmpz_add(VALUE self, VALUE arg);
|
99
|
+
extern VALUE r_gmpz_add_self(VALUE self, VALUE arg);
|
100
|
+
extern VALUE r_gmpz_sub(VALUE self, VALUE arg);
|
101
|
+
extern VALUE r_gmpz_sub_self(VALUE self, VALUE arg);
|
102
|
+
extern VALUE r_gmpz_mul(VALUE self, VALUE arg);
|
103
|
+
|
104
|
+
// Integer Exponentiation
|
105
|
+
extern VALUE r_gmpzsg_pow(VALUE klass, VALUE base, VALUE exp);
|
106
|
+
|
107
|
+
// Number Theoretic Functions
|
108
|
+
extern VALUE r_gmpz_remove(VALUE self, VALUE arg);
|
109
|
+
|
110
|
+
// Integer Comparisons
|
111
|
+
extern VALUE r_gmpz_eq(VALUE self, VALUE arg);
|
112
|
+
extern VALUE r_gmpz_cmp(VALUE self, VALUE arg);
|
113
|
+
extern VALUE r_gmpz_cmpabs(VALUE self, VALUE arg);
|
114
|
+
|
115
|
+
// _unsorted_
|
116
|
+
extern VALUE r_gmpz_div(VALUE self, VALUE arg);
|
117
|
+
extern VALUE r_gmpz_is_probab_prime(int argc, VALUE* argv, VALUE self);
|
118
|
+
extern VALUE r_gmpz_popcount(VALUE self);
|
119
|
+
extern VALUE r_gmpz_jacobi(VALUE self);
|
120
|
+
extern VALUE r_gmpz_legendre(VALUE self);
|
121
|
+
extern VALUE r_gmpz_setbit(VALUE self, VALUE bitnr, VALUE set_to);
|
122
|
+
extern VALUE r_gmpz_getbit(VALUE self, VALUE bitnr);
|
123
|
+
extern VALUE r_gmpz_scan0(VALUE self, VALUE bitnr);
|
124
|
+
extern VALUE r_gmpz_scan1(VALUE self, VALUE bitnr);
|
125
|
+
extern VALUE r_gmpz_powm(VALUE self, VALUE exp, VALUE mod);
|
126
|
+
extern VALUE r_gmpz_sgn(VALUE self);
|
127
|
+
extern int mpz_cmp_value(MP_INT *OP, VALUE arg);
|
128
|
+
|
129
|
+
|
130
|
+
|
131
|
+
/* from gmpq.h */
|
132
|
+
|
133
|
+
// Initializing Rationals
|
134
|
+
extern VALUE r_gmpqsg_new(int argc, VALUE *argv, VALUE klass);
|
135
|
+
extern VALUE r_gmpmod_q(int argc, VALUE *argv, VALUE module);
|
136
|
+
extern VALUE r_gmpq_swap(VALUE self, VALUE arg);
|
137
|
+
|
138
|
+
// Rational Conversions
|
139
|
+
extern VALUE r_gmpq_to_d(VALUE self);
|
140
|
+
extern VALUE r_gmpq_to_s(VALUE self);
|
141
|
+
|
142
|
+
// Rational Arithmetic
|
143
|
+
extern VALUE r_gmpq_add(VALUE self, VALUE arg);
|
144
|
+
extern VALUE r_gmpq_sub(VALUE self, VALUE arg);
|
145
|
+
extern VALUE r_gmpq_mul(VALUE self, VALUE arg);
|
146
|
+
extern VALUE r_gmpq_div(VALUE self, VALUE arg);
|
147
|
+
extern VALUE r_gmpq_neg(VALUE self);
|
148
|
+
extern VALUE r_gmpq_neg_self(VALUE self);
|
149
|
+
extern VALUE r_gmpq_abs(VALUE self);
|
150
|
+
extern VALUE r_gmpq_abs_self(VALUE self);
|
151
|
+
extern VALUE r_gmpq_inv(VALUE self);
|
152
|
+
extern VALUE r_gmpq_inv_self(VALUE self);
|
153
|
+
|
154
|
+
// Comparing Rationals
|
155
|
+
extern VALUE r_gmpq_eq(VALUE self, VALUE arg);
|
156
|
+
extern VALUE r_gmpq_cmp(VALUE self, VALUE arg);
|
157
|
+
extern int mpq_cmp_value(MP_RAT *OP, VALUE arg);
|
158
|
+
extern VALUE r_gmpq_sgn(VALUE self);
|
159
|
+
|
160
|
+
// Applying Integer Functions
|
161
|
+
extern VALUE r_gmpq_num(VALUE self);
|
162
|
+
extern VALUE r_gmpq_den(VALUE self);
|
163
|
+
|
164
|
+
// _unsorted_
|
165
|
+
|
166
|
+
|
167
|
+
/* from gmpf.h */
|
168
|
+
|
169
|
+
// Initializing, Assigning Floats
|
170
|
+
extern VALUE r_gmpfsg_new(int argc, VALUE *argv, VALUE klass);
|
171
|
+
extern VALUE r_gmpf_initialize(int argc, VALUE *argv, VALUE self);
|
172
|
+
extern void mpf_set_value(MP_FLOAT *self_val, VALUE arg);
|
173
|
+
extern VALUE r_gmpmod_f(int argc, VALUE *argv, VALUE module);
|
174
|
+
|
175
|
+
// Converting Floats
|
176
|
+
extern VALUE r_gmpf_to_d(VALUE self);
|
177
|
+
extern VALUE r_gmpf_to_s(VALUE self);
|
178
|
+
|
179
|
+
// Float Arithmetic
|
180
|
+
extern VALUE r_gmpf_add(VALUE self, VALUE arg);
|
181
|
+
extern VALUE r_gmpf_sub(VALUE self, VALUE arg);
|
182
|
+
extern VALUE r_gmpf_mul(VALUE self, VALUE arg);
|
183
|
+
extern VALUE r_gmpf_div(VALUE self, VALUE arg);
|
184
|
+
|
185
|
+
// Float Comparison
|
186
|
+
extern VALUE r_gmpf_eq(VALUE self, VALUE arg);
|
187
|
+
extern VALUE r_gmpf_cmp(VALUE self, VALUE arg);
|
188
|
+
extern int mpf_cmp_value(MP_FLOAT *OP, VALUE arg);
|
189
|
+
|
190
|
+
// _unsorted_
|
191
|
+
extern VALUE r_gmpf_sgn(VALUE self);
|
192
|
+
extern VALUE r_gmpf_get_prec(VALUE self);
|
193
|
+
|
194
|
+
|
195
|
+
extern void init_gmpz();
|
196
|
+
extern void init_gmpq();
|
197
|
+
extern void init_gmpf();
|
198
|
+
|
199
|
+
#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.tex
ADDED
@@ -0,0 +1,183 @@
|
|
1
|
+
\documentclass[pdftex,10pt]{article}
|
2
|
+
\usepackage{amsmath,amsfonts,url}
|
3
|
+
\usepackage[pdftex]{graphicx}
|
4
|
+
\setlength{\parindent}{0pt}
|
5
|
+
\newcommand{\HRule}{\rule{\linewidth}{0.8mm}}
|
6
|
+
\newcommand{\sectionline}{\rule{1.0\linewidth}{2.0pt}}
|
7
|
+
\def\cour{\fontfamily{pcr}\selectfont}
|
8
|
+
\usepackage[top=1.2in, bottom=0.8in, left=0.8in, right=0.8in]{geometry}
|
9
|
+
\setcounter{tocdepth}{3}
|
10
|
+
\title{gmp - Ruby bindings to the GMP library}
|
11
|
+
\date{September 27, 2009}
|
12
|
+
\author{Sam Rawlins}
|
13
|
+
\begin{document}
|
14
|
+
\huge{gmp}\\
|
15
|
+
\HRule
|
16
|
+
\begin{flushright}
|
17
|
+
\large{Ruby bindings to the GMP library}\\
|
18
|
+
\large{Edition 0.1.5}\\
|
19
|
+
\large{27 September 2009}\\
|
20
|
+
\end{flushright}
|
21
|
+
\vfill
|
22
|
+
\large{written by Sam Rawlins}\\
|
23
|
+
\large{with extensive quoting from the GMP Manual}
|
24
|
+
\newpage
|
25
|
+
|
26
|
+
\vfill
|
27
|
+
This manual describes how to use the gmp Ruby gem, which provides bindings to
|
28
|
+
the GNU multiple precision arithmetic library, version 4.3.x.\\
|
29
|
+
\\
|
30
|
+
Copyright 2009 Sam Rawlins.\\
|
31
|
+
No license yet.
|
32
|
+
\newpage
|
33
|
+
|
34
|
+
\tableofcontents
|
35
|
+
\newpage
|
36
|
+
|
37
|
+
\section{Introduction to GNU MP}
|
38
|
+
|
39
|
+
This entire page is copied verbatim from the GMP Manual.\\\\
|
40
|
+
|
41
|
+
GNU MP is a portable library written in C for arbitrary precision arithmetic on
|
42
|
+
integers, rational numbers, and floating-point numbers. It aims to provide the
|
43
|
+
fastest possible arithmetic for all applications that need higher precision
|
44
|
+
than is directly supported by the basic C types.\\
|
45
|
+
\\
|
46
|
+
Many applications use just a few hundred bits of precision; but some
|
47
|
+
applications may need thousands or even millions of bits. GMP is designed to
|
48
|
+
give good performance for both, by choosing algorithms based on the sizes of
|
49
|
+
the operands, and by carefully keeping the overhead at a minimum.\\
|
50
|
+
\\
|
51
|
+
The speed of GMP is achieved by using fullwords as the basic arithmetic type,
|
52
|
+
by using sophisticated algorithms, by including carefully optimized assembly
|
53
|
+
code for the most common inner loops for many different CPUs, and by a general
|
54
|
+
emphasis on speed (as opposed to simplicity or elegance).\\
|
55
|
+
\\
|
56
|
+
There is assembly code for these CPUs: ARM, DEC Alpha 21064, 21164, and 21264,
|
57
|
+
AMD 29000, AMD K6, K6-2, Athlon, and Athlon64, Hitachi SuperH and SH-2, HPPA
|
58
|
+
1.0, 1.1, and 2.0, Intel Pentium, Pentium Pro/II/III, Pentium 4, generic x86,
|
59
|
+
Intel IA-64, i960, Motorola MC68000, MC68020, MC88100, and MC88110,
|
60
|
+
Motorola/IBM PowerPC 32 and 64, National NS32000, IBM POWER, MIPS R3000, R4000,
|
61
|
+
SPARCv7, SuperSPARC, generic SPARCv8, UltraSPARC, DEC VAX, and Zilog Z8000.
|
62
|
+
Some optimizations also for Cray vector systems, Clipper, IBM ROMP (RT), and
|
63
|
+
Pyramid AP/XP.\\
|
64
|
+
\\
|
65
|
+
For up-to-date information on GMP, please see the GMP web pages at\\
|
66
|
+
\\
|
67
|
+
\indent \texttt{http://gmplib.org/}\\
|
68
|
+
|
69
|
+
The latest version of the library is available at\\
|
70
|
+
\\
|
71
|
+
\texttt{ftp://ftp.gnu.org/gnu/gmp/}\\
|
72
|
+
\\
|
73
|
+
Many sites around the world mirror '\texttt{ftp.gnu.org}', please use a mirror
|
74
|
+
near you, see \texttt{http://www.gnu.org/order/ftp.html} for a full list.\\
|
75
|
+
\\
|
76
|
+
There are three public mailing lists of interest. One for release
|
77
|
+
announcements, one for general questions and discussions about usage of the GMP
|
78
|
+
library, and one for bug reports. For more information, see\\
|
79
|
+
\\
|
80
|
+
\texttt{http://gmplib.org/mailman/listinfo/}.\\
|
81
|
+
\\
|
82
|
+
The proper place for bug reports is gmp-bugs@gmplib.org. See Chapter 4
|
83
|
+
[Reporting Bugs], page 28 for information about reporting bugs.
|
84
|
+
|
85
|
+
\section{Introduction to the gmp gem}
|
86
|
+
|
87
|
+
The gmp Ruby gem is a Ruby library that provides bindings to GMP. The gem is
|
88
|
+
incomplete, and will likely only include a subset of the GMP functions. It is
|
89
|
+
built as a C extension for ruby, interacting with gmp.h. The gmp gem is not
|
90
|
+
endorsed or supported by GNU or the GMP team. The gmp gem also does not ship
|
91
|
+
with GMP, so GMP must be compiled separately.
|
92
|
+
|
93
|
+
\section{Installing the gmp gem}
|
94
|
+
|
95
|
+
\subsection{Prerequisites}
|
96
|
+
OK. First, we've got a few requirements. To install the gmp gem, you need one
|
97
|
+
of the following versions of Ruby:
|
98
|
+
\begin{itemize}
|
99
|
+
\item (MRI) Ruby 1.8.6 - tested lightly.
|
100
|
+
\item (MRI) Ruby 1.8.7 - tested seriously.
|
101
|
+
\item (MRI) Ruby 1.9.1 - more of a "release candidate" state. Please report
|
102
|
+
bugs.
|
103
|
+
\end{itemize}
|
104
|
+
As you can see only Matz's Ruby Interpreter (MRI) is supported. I haven't even
|
105
|
+
put a thought into trying other interpreters/VMs. I intend to look into FFI,
|
106
|
+
which supposedly will allow me to load this extension into JRuby and Rubinius,
|
107
|
+
not sure about others...\\
|
108
|
+
|
109
|
+
Next is the platform, the combination of the architecture (processor) and OS.
|
110
|
+
As far as I can tell, if you can compile GMP and Ruby on a given platform, you
|
111
|
+
can use the gmp gem there too. Please report problems with that hypothesis.\\
|
112
|
+
|
113
|
+
Lastly, GMP. GMP must be compiled and working. "and working" means you ran "make check" while installing GMP. The following versions of GMP have been tested:
|
114
|
+
\begin{itemize}
|
115
|
+
\item GMP 4.3.1
|
116
|
+
\end{itemize}
|
117
|
+
|
118
|
+
That's all. I don't intend to test any older versions, maybe 4.3.0 for completeness.\\
|
119
|
+
|
120
|
+
Here is a table of the exact environments I have tested the gmp gem on:\\\\
|
121
|
+
|
122
|
+
\begin{tabular}{|l|r|r|} \hline
|
123
|
+
Platform & Ruby & GMP \\ \hline \hline
|
124
|
+
Cygwin on x86 & (MRI) Ruby 1.8.7 & GMP 4.3.1 \\ \hline
|
125
|
+
Linux (LinuxMint 7) on x86 & (MRI) Ruby 1.8.7 & GMP 4.3.1 \\ \hline
|
126
|
+
Mac OS X 10.5.7 on x86 (32-bit) & (MRI) Ruby 1.8.6 & GMP 4.3.1 \\ \hline
|
127
|
+
Mac OS X 10.5.7 on x86 (32-bit) & (MRI) Ruby 1.9.1 & GMP 4.3.1 \\ \hline
|
128
|
+
\end{tabular}
|
129
|
+
|
130
|
+
\subsection{Installing}
|
131
|
+
You may clone the gmp gem's git repository with:\\
|
132
|
+
\\
|
133
|
+
\hangindent=0.5cm \texttt{git clone git://github.com/srawlins/gmp.git}\\
|
134
|
+
|
135
|
+
Or you may install the gem from github:\\
|
136
|
+
\\
|
137
|
+
\hangindent=0.5cm \texttt{gem install srawlins-gmp}\\
|
138
|
+
|
139
|
+
At this time, the gem does not self-compile (how does that work?). To compile the C
|
140
|
+
extensions, do the following:\\
|
141
|
+
\\
|
142
|
+
\hangindent=0.5cm \texttt{cd <srawlins-gmp gem directory>/ext}\\
|
143
|
+
\hangindent=0.5cm \texttt{ruby extconf.rb}\\
|
144
|
+
\hangindent=0.5cm \texttt{make}\\
|
145
|
+
|
146
|
+
There shouldn't be any errors, or warnings.
|
147
|
+
|
148
|
+
\section{GMP and gmp gem basics}
|
149
|
+
|
150
|
+
\subsection{Classes}
|
151
|
+
The gmp gem includes the namespace \texttt{GMP} and three classes within \texttt{GMP}:
|
152
|
+
\begin{itemize}
|
153
|
+
\item \texttt{GMP::Z} - Methods for signed integer arithmetic. There are at least 35
|
154
|
+
methods here (still accounting).
|
155
|
+
\item \texttt{GMP::Q} - Methods for rational number arithmetic. There are at least 6
|
156
|
+
methods here (still accounting).
|
157
|
+
\item \texttt{GMP::F} - Methods for floating-point arithmetic. There are at least 0
|
158
|
+
methods here (still accounting).
|
159
|
+
\end{itemize}
|
160
|
+
|
161
|
+
In addition to the above three classes, there is also one constant within \texttt{GMP}:
|
162
|
+
\begin{itemize}
|
163
|
+
\item \texttt{GMP::GMP\_VERSION} - The version of GMP compiled into the gmp gem.
|
164
|
+
\end{itemize}
|
165
|
+
|
166
|
+
\section{Integer Functions}
|
167
|
+
|
168
|
+
\subsection{Initializing, Assigning Integers}
|
169
|
+
|
170
|
+
\large{\textbf{GMP::Z.new(a = 0)}}\\
|
171
|
+
\large{\textbf{GMP::Z(a = 0)}}\\
|
172
|
+
This method creates a new \texttt{GMP::Z} integer. It takes one optional argument for the value of the integer. This argument can be one of several classes. Here are some examples:
|
173
|
+
\begin{verbatim}
|
174
|
+
GMP::Z.new #=> 0 (default)
|
175
|
+
GMP::Z.new(1) #=> 1 (Ruby Fixnum)
|
176
|
+
GMP::Z.new("127") #=> 127 (Ruby String)
|
177
|
+
GMP::Z.new(4294967296) #=> 4294967296 (Ruby Bignum)
|
178
|
+
GMP::Z.new(GMP::Z.new(31)) #=> 31 (GMP Integer)
|
179
|
+
\end{verbatim}
|
180
|
+
|
181
|
+
There is also a convenience method available, \texttt{GMP::Z()}.\\
|
182
|
+
|
183
|
+
\end{document}
|
data/test/README
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
TODO: Port everything to Test::Unit framework
|
2
|
+
Test files 1-6 ported.
|
3
|
+
|
4
|
+
Current version passes:
|
5
|
+
1-23
|
6
|
+
Current version fails on these tests because:
|
7
|
+
none
|
8
|
+
Tests:
|
9
|
+
1* initializations and to_s
|
10
|
+
2* basic integer arithmetics and coersion to Z
|
11
|
+
3* integer logical operators
|
12
|
+
4* comparisions between Z, Q, FixNum and BigNum
|
13
|
+
5* basic rational arithmetics and coersion to Q
|
14
|
+
6 bit operations, scan0, scan1
|
15
|
+
7* exponentiation and exponentiation modulo
|
16
|
+
8* divide by zero exceptions
|
17
|
+
9* sgn, neg, abs
|
18
|
+
10* fibonacci, factorial, nextprime
|
19
|
+
11* swap
|
20
|
+
12* floor, ceil, truncate
|
21
|
+
13* to_i, to_d
|
22
|
+
14* shifts, last_bits
|
23
|
+
15* logical tests, roots
|
24
|
+
16* floating point init with and without explicit precision
|
25
|
+
17 basic floating point arithmetics and coersion to F
|
26
|
+
18 default_prec and default_prec=
|
27
|
+
19 integer division methods
|
28
|
+
20 mpfr - exp and log
|
29
|
+
21 mpfr - trigonometry
|
30
|
+
22 mpfr - type tests
|
31
|
+
23 mpfr - sqrt and power
|
32
|
+
TODO:
|
33
|
+
jacobi, legendre, remove
|
34
|
+
gcd, lcm
|
35
|
+
cmpabs
|
36
|
+
integer and integer->rational division, modulo
|
37
|
+
more number theoretic functions
|
38
|
+
random numbers
|
39
|
+
range error exceptions
|
40
|
+
full coverage?
|
41
|
+
use more assert_in_delta
|