gmp 0.5.3 → 0.5.23
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +19 -0
- data/FEATURES.html +393 -0
- data/README.rdoc +64 -32
- data/ext/gmp.c +5 -55
- data/ext/gmpf.c +300 -179
- data/ext/gmpq.c +81 -111
- data/ext/gmprandstate.c +30 -0
- data/ext/gmpz.c +543 -424
- data/ext/gmpz.h +0 -8
- data/ext/ruby_gmp.h +14 -20
- data/manual.pdf +0 -0
- data/manual.tex +56 -11
- data/test/gmp_tgcd.rb +126 -0
- data/test/mpfr_tconst_euler.rb +36 -0
- data/test/tc_mpfr_functions.rb +48 -17
- data/test/tc_q.rb +80 -0
- data/test/tc_q_basic.rb +2 -2
- data/test/tc_z.rb +46 -16
- data/test/tc_z_submul.rb +94 -0
- data/test/tc_z_to_dis.rb +69 -0
- data/test/unit_tests.rb +8 -5
- metadata +10 -9
- data/benchmark/gexpr +0 -0
- data/test/tc_z_to_d_to_i.rb +0 -24
- data/test/test-12.rb +0 -14
- data/test/test-19.rb +0 -13
data/ext/gmpz.h
CHANGED
data/ext/ruby_gmp.h
CHANGED
@@ -32,26 +32,23 @@
|
|
32
32
|
typedef __mpfr_struct MP_FLOAT;
|
33
33
|
#else
|
34
34
|
typedef __mpf_struct MP_FLOAT;
|
35
|
+
/*
|
36
|
+
* Here, MPFR is not included, so we are pure GMP. In GMP, mpf_get_prec returns
|
37
|
+
* an unsigned long int, so we will too.
|
38
|
+
*/
|
39
|
+
typedef unsigned long mpfr_prec_t;
|
35
40
|
#endif /* HAVE_MPF2MPFR_H */
|
36
41
|
|
42
|
+
#if __GNU_MP_VERSION < 5
|
43
|
+
typedef unsigned long int mp_bitcnt_t;
|
44
|
+
#endif
|
45
|
+
|
37
46
|
/*
|
38
47
|
I don't like this solution, because in gmp.h, all of these typedefs are
|
39
48
|
marked with "gmp 1 source compatibility". :(.
|
40
49
|
*/
|
41
50
|
typedef __gmp_randstate_struct MP_RANDSTATE;
|
42
51
|
|
43
|
-
/*
|
44
|
-
* Here, MPFR is not included, so we are pure GMP. In GMP, mpf_get_prec returns
|
45
|
-
* an unsigned long int, so we will too.
|
46
|
-
*/
|
47
|
-
#ifndef MPFR
|
48
|
-
typedef unsigned long mpfr_prec_t;
|
49
|
-
/*
|
50
|
-
* Here, MPFR is not included, so we are pure GMP. In GMP, mpf_get_prec returns
|
51
|
-
* an unsigned long int, so we will too.
|
52
|
-
*/
|
53
|
-
#endif
|
54
|
-
|
55
52
|
#define mpz_get_struct(ruby_var,c_var) { Data_Get_Struct(ruby_var, MP_INT, c_var); }
|
56
53
|
#define mpq_get_struct(ruby_var,c_var) { Data_Get_Struct(ruby_var, MP_RAT, c_var); }
|
57
54
|
#define mpf_get_struct(ruby_var,c_var) { Data_Get_Struct(ruby_var, MP_FLOAT, c_var); }
|
@@ -69,15 +66,15 @@ typedef unsigned long mpfr_prec_t;
|
|
69
66
|
#define GMPQ_P(value) (rb_obj_is_instance_of(value, cGMP_Q) == Qtrue)
|
70
67
|
#define GMPF_P(value) (rb_obj_is_instance_of(value, cGMP_F) == Qtrue)
|
71
68
|
#define mpz_set_bignum(var_mpz,var_bignum) { \
|
72
|
-
VALUE tmp = rb_funcall (var_bignum, rb_intern ("to_s"),
|
73
|
-
mpz_set_str (var_mpz, StringValuePtr (tmp),
|
69
|
+
VALUE tmp = rb_funcall (var_bignum, rb_intern ("to_s"), 1, INT2FIX(32)); \
|
70
|
+
mpz_set_str (var_mpz, StringValuePtr (tmp), 32); \
|
74
71
|
}
|
75
72
|
#define mpz_temp_alloc(var) { var=malloc(sizeof(MP_INT)); }
|
76
73
|
#define mpz_temp_init(var) { mpz_temp_alloc(var); mpz_init(var); }
|
77
74
|
#define mpz_temp_from_bignum(var,var_bignum) { \
|
78
75
|
mpz_temp_alloc(var); \
|
79
|
-
VALUE tmp = rb_funcall (var_bignum, rb_intern ("to_s"),
|
80
|
-
mpz_init_set_str (var, StringValuePtr (tmp),
|
76
|
+
VALUE tmp = rb_funcall (var_bignum, rb_intern ("to_s"), 1, INT2FIX(32)); \
|
77
|
+
mpz_init_set_str (var, StringValuePtr (tmp), 32); \
|
81
78
|
}
|
82
79
|
#define mpz_temp_free(var) { mpz_clear(var); free(var); }
|
83
80
|
#define mpf_temp_alloc(var) { var=malloc(sizeof(MP_FLOAT)); }
|
@@ -128,6 +125,7 @@ typedef unsigned long mpfr_prec_t;
|
|
128
125
|
#define EXPECTED_ZX "Expected GMP::Z or Fixnum"
|
129
126
|
#define EXPECTED_X "Expected Fixnum"
|
130
127
|
#define EXPECTED_Z "Expected GMP::Z"
|
128
|
+
#define EXPECTED_FD "Expected GMP::F or Float"
|
131
129
|
#define typeerror(expected) rb_raise(rb_eTypeError, EXPECTED_##expected)
|
132
130
|
#define typeerror_as(expected, argname) rb_raise(rb_eTypeError, EXPECTED_##expected " as " argname)
|
133
131
|
|
@@ -226,10 +224,6 @@ extern VALUE r_gmpq_add(VALUE self, VALUE arg);
|
|
226
224
|
extern VALUE r_gmpq_sub(VALUE self, VALUE arg);
|
227
225
|
extern VALUE r_gmpq_mul(VALUE self, VALUE arg);
|
228
226
|
extern VALUE r_gmpq_div(VALUE self, VALUE arg);
|
229
|
-
extern VALUE r_gmpq_neg(VALUE self);
|
230
|
-
extern VALUE r_gmpq_neg_self(VALUE self);
|
231
|
-
extern VALUE r_gmpq_abs(VALUE self);
|
232
|
-
extern VALUE r_gmpq_abs_self(VALUE self);
|
233
227
|
extern VALUE r_gmpq_inv(VALUE self);
|
234
228
|
extern VALUE r_gmpq_inv_self(VALUE self);
|
235
229
|
|
data/manual.pdf
CHANGED
Binary file
|
data/manual.tex
CHANGED
@@ -34,8 +34,8 @@
|
|
34
34
|
\huge{gmp} &\\
|
35
35
|
\midrule[3pt]
|
36
36
|
\multicolumn{2}{r}{\large{Ruby bindings to the GMP library}}\\
|
37
|
-
\multicolumn{2}{r}{\large{Edition 0.5.
|
38
|
-
\multicolumn{2}{r}{\large{
|
37
|
+
\multicolumn{2}{r}{\large{Edition 0.5.23}}\\
|
38
|
+
\multicolumn{2}{r}{\large{04 October 2010}}
|
39
39
|
\end{tabular}
|
40
40
|
|
41
41
|
\vfill
|
@@ -146,11 +146,10 @@ of the following versions of Ruby:
|
|
146
146
|
\item (MRI) Ruby 1.8.7 - tested seriously.
|
147
147
|
\item (MRI) Ruby 1.9.1 - tested seriously.
|
148
148
|
\item (MRI) Ruby 1.9.2 - tested seriously.
|
149
|
+
\item (REE) Ruby 1.8.7 - tested lightly.
|
149
150
|
\end{itemize}
|
150
|
-
As you can see only Matz's Ruby Interpreter (MRI) is supported. I
|
151
|
-
|
152
|
-
which supposedly will allow me to load this extension into JRuby and Rubinius,
|
153
|
-
not sure about others...\\
|
151
|
+
As you can see only Matz's Ruby Interpreter (MRI) is supported. I've just started to poke
|
152
|
+
around with REE. Everything seems to work on REE 1.8.7 on Linux, x86 and x86\_64.\\
|
154
153
|
|
155
154
|
Next is the platform, the combination of the architecture (processor) and OS.
|
156
155
|
As far as I can tell, if you can compile GMP and Ruby (and optionally MPFR) on
|
@@ -194,6 +193,12 @@ the given version of MPFR:\\\\
|
|
194
193
|
& (MRI) Ruby 1.9.1 & GMP 5.0.1 & (3.0.0) \\
|
195
194
|
& (MRI) Ruby 1.9.2 & GMP 4.3.2 & (2.4.2) \\
|
196
195
|
& (MRI) Ruby 1.9.2 & GMP 5.0.1 & (3.0.0) \\ \hline
|
196
|
+
Windows 7 on x86\_64 (64-bit) & (MRI) Ruby 1.8.7 & GMP 4.3.2 & (2.4.2) \\
|
197
|
+
& (MRI) Ruby 1.8.7 & GMP 5.0.1 & (3.0.0) \\
|
198
|
+
& (MRI) Ruby 1.9.1 & GMP 4.3.2 & (2.4.2) \\
|
199
|
+
& (MRI) Ruby 1.9.1 & GMP 5.0.1 & (3.0.0) \\
|
200
|
+
& (MRI) Ruby 1.9.2 & GMP 4.3.2 & (2.4.2) \\
|
201
|
+
& (MRI) Ruby 1.9.2 & GMP 5.0.1 & (3.0.0) \\ \hline
|
197
202
|
Windows XP on x86 (32-bit) & (MRI) Ruby 1.9.1 & GMP 4.3.2 & (2.4.2) \\
|
198
203
|
& (MRI) Ruby 1.9.1 & GMP 5.0.1 & (3.0.0) \\ \hline
|
199
204
|
\end{tabular}\\\\
|
@@ -266,6 +271,8 @@ In addition to the above four classes, there are also four constants within \tex
|
|
266
271
|
\item \texttt{GMP::GMP\_CFLAGS} - The compiler flags used to compile GMP linked into
|
267
272
|
the gmp gem
|
268
273
|
\item \texttt{GMP::GMP\_BITS\_PER\_LIMB} - The number of bits per limb
|
274
|
+
\item \texttt{GMP::GMP\_NUMB\_MAX} - The maximum value that can be stored in the number
|
275
|
+
part of a limb.
|
269
276
|
\end{itemize}
|
270
277
|
|
271
278
|
\section{MPFR basics}
|
@@ -278,6 +285,8 @@ methods in \texttt{GMP::F}.
|
|
278
285
|
There are additional constants within \texttt{GMP} when MPFR is linked:
|
279
286
|
\begin{itemize}
|
280
287
|
\item \texttt{GMP::MPFR\_VERSION} - The version of MPFR linked into the gmp gem.
|
288
|
+
\item \texttt{GMP::MPFR\_PREC\_MIN} - The minimum precision available.
|
289
|
+
\item \texttt{GMP::MPFR\_PREC\_MAX} - The maximum precision available
|
281
290
|
\item \texttt{GMP::GMP\_RNDN} - Rounding mode representing "round to nearest."
|
282
291
|
\item \texttt{GMP::GMP\_RNDZ} - Rounding mode representing "round toward zero."
|
283
292
|
\item \texttt{GMP::GMP\_RNDU} - Rounding mode representing "round toward positive
|
@@ -458,12 +467,24 @@ There is also a convenience method available, \texttt{GMP::Z()}.\\
|
|
458
467
|
|
459
468
|
\begin{tabular}{p{\methwidth} l r}
|
460
469
|
\toprule
|
461
|
-
\textbf{addmul!} & & \textit{integer}.addmul!(\textit{
|
470
|
+
\textbf{addmul!} & & \textit{integer}.addmul!(\textit{b}, \textit{c}) $\rightarrow$ \textit{numeric} \\
|
462
471
|
\cmidrule(r){2-3}
|
463
472
|
& \multicolumn{2}{p{\defnwidth}}{
|
464
|
-
Sets \textit{integer} to the sum of \textit{integer} and the product of \textit{
|
465
|
-
\textit{
|
466
|
-
\textit{
|
473
|
+
Sets \textit{integer} to the sum of \textit{integer} and the product of \textit{b} and
|
474
|
+
\textit{c}. This destructive method calculates the result in place. Both \textit{b} and
|
475
|
+
\textit{c} can be an instance of \gmpz, \textit{Fixnum}, or \textit{Bignum}.
|
476
|
+
}
|
477
|
+
\end{tabular}
|
478
|
+
\newline\newline
|
479
|
+
|
480
|
+
\begin{tabular}{p{\methwidth} l r}
|
481
|
+
\toprule
|
482
|
+
\textbf{submul!} & & \textit{integer}.submul!(\textit{b}, \textit{c}) $\rightarrow$ \textit{numeric} \\
|
483
|
+
\cmidrule(r){2-3}
|
484
|
+
& \multicolumn{2}{p{\defnwidth}}{
|
485
|
+
Sets \textit{integer} to the difference of \textit{integer} and the product of \textit{b} and
|
486
|
+
\textit{c}. This destructive method calculates the result in place. Both \textit{b} and
|
487
|
+
\textit{c} can be an instance of \gmpz, \textit{Fixnum}, or \textit{Bignum}.
|
467
488
|
}
|
468
489
|
\end{tabular}
|
469
490
|
\newline\newline
|
@@ -583,6 +604,17 @@ There is also a convenience method available, \texttt{GMP::Z()}.\\
|
|
583
604
|
or $Bignum$. The return object's class is always \gmpz.
|
584
605
|
}
|
585
606
|
\end{tabular}
|
607
|
+
\newline\newline
|
608
|
+
|
609
|
+
\begin{tabular}{p{\methwidth} l r}
|
610
|
+
\toprule
|
611
|
+
\textbf{divisible?} & & \textit{integer}.divisible? \textit{numeric} $\rightarrow$ \textit{boolean}\\
|
612
|
+
\cmidrule(r){2-3}
|
613
|
+
& \multicolumn{2}{p{\defnwidth}}{
|
614
|
+
Returns whether $integer$ is divisible by $numeric$. $numeric$ can be an instance of \gmpz, $Fixnum$,
|
615
|
+
or $Bignum$.
|
616
|
+
}
|
617
|
+
\end{tabular}
|
586
618
|
|
587
619
|
\newpage
|
588
620
|
\subsection{Integer Exponentiation}
|
@@ -675,7 +707,7 @@ There is also a convenience method available, \texttt{GMP::Z()}.\\
|
|
675
707
|
|
676
708
|
\begin{tabular}{p{\methwidth} l r}
|
677
709
|
\toprule
|
678
|
-
\textbf{
|
710
|
+
\textbf{probab\_prime?} & & $integer$.probab\_prime?($reps = 5$) $\rightarrow$ 0, 1, or 2 \\
|
679
711
|
\cmidrule(r){2-3}
|
680
712
|
& \multicolumn{2}{p{\defnwidth}}{
|
681
713
|
Determine whether $integer$ is prime. Returns 2 if $integer$ is definitely prime,
|
@@ -726,6 +758,19 @@ There is also a convenience method available, \texttt{GMP::Z()}.\\
|
|
726
758
|
\end{tabular}
|
727
759
|
\newline\newline
|
728
760
|
|
761
|
+
\begin{tabular}{p{\methwidth} l r}
|
762
|
+
\toprule
|
763
|
+
\textbf{gcdext} & & $a$.gcd($b$) $\rightarrow$ $g$, $s$, $t$ \\
|
764
|
+
\cmidrule(r){2-3}
|
765
|
+
& \multicolumn{2}{p{\defnwidth}}{
|
766
|
+
Computes the greatest common divisor of $a$ and $b$, in addition to $s$ and $t$, the
|
767
|
+
coefficients satisfying $a*s + b*t = g$. $g$ will always be positive, even if $a$ or
|
768
|
+
$b$ is negative. $s$ and $t$ are chosen such that $|s| <= |b|$ and $|t| <= |a|$. $b$
|
769
|
+
can be an instance of \gmpz, $Fixnum$, or $Bignum$.
|
770
|
+
}
|
771
|
+
\end{tabular}
|
772
|
+
\newline\newline
|
773
|
+
|
729
774
|
\begin{tabular}{p{\methwidth} l r}
|
730
775
|
\toprule
|
731
776
|
\textbf{invert} & & $a$.invert($m$) $\rightarrow$ $integer$ \\
|
data/test/gmp_tgcd.rb
ADDED
@@ -0,0 +1,126 @@
|
|
1
|
+
require './test_helper'
|
2
|
+
|
3
|
+
class GMP_TGCD < Test::Unit::TestCase
|
4
|
+
def setup
|
5
|
+
@rand_state = GMP::RandState.new
|
6
|
+
@min_operand_bitsize = 1
|
7
|
+
end
|
8
|
+
|
9
|
+
def one_test(op1, op2, ref, i)
|
10
|
+
g1, s, t = op1.gcdext(op2)
|
11
|
+
|
12
|
+
if ref# and ref != g1
|
13
|
+
assert_true(ref == g1, "GMP::Z#gcdext should work...")
|
14
|
+
end
|
15
|
+
|
16
|
+
gcdext_valid_p(op1, op2, g1, s)
|
17
|
+
|
18
|
+
g2 = op1.gcd(op2)
|
19
|
+
assert_equal(g1, g2, "gcd and gcdext should produce the same gcd.")
|
20
|
+
|
21
|
+
g2, temp1, temp2 = op1.gcdext(op2)
|
22
|
+
temp1 *= op1
|
23
|
+
temp2 *= op2
|
24
|
+
temp1 += temp2
|
25
|
+
assert_true(g1 == g2 || g2 == temp1, "gcdext should work...")
|
26
|
+
end
|
27
|
+
|
28
|
+
def gcdext_valid_p(a, b, g, s)
|
29
|
+
assert_true(g >= 0, "When [g, s, t] = a.gcdext(b), g must > 0 (g=#{g}, s=#{s}, a=#{a}, b=#{b})")
|
30
|
+
|
31
|
+
if a.sgn == 0
|
32
|
+
assert_true(g.cmpabs(b) == 0, "When [g, s, t] = a.gcdext(b), if a == 0, g must == |b|")
|
33
|
+
assert_true(s == 0, "When [g, s, t] = a.gcdext(b), if a == 0, s should == 0")
|
34
|
+
return
|
35
|
+
end
|
36
|
+
|
37
|
+
if b.sgn == 0
|
38
|
+
assert_true(g.cmpabs(a) == 0, "When [g, s, t] = a.gcdext(b), if b == 0, g must == |a|")
|
39
|
+
assert_true(s == a.sgn, "When [g, s, t] = a.gcdext(b), if a == 0, s should == a.sgn")
|
40
|
+
return
|
41
|
+
end
|
42
|
+
|
43
|
+
assert_false(g.sgn <= 0, "When [g, s, t] = a.gcdext(b), if neither a == 0 nor b == 0, g must > 0")
|
44
|
+
|
45
|
+
temp1 = a.tdiv(g)
|
46
|
+
temp3 = a.tmod(g)
|
47
|
+
assert_true(temp3.sgn == 0, "When [g, s, t] = a.gcdext(b), g must divide a.")
|
48
|
+
temp2 = b.tdiv(g)
|
49
|
+
temp3 = b.tmod(g)
|
50
|
+
assert_true(temp3.sgn == 0, "When [g, s, t] = a.gcdext(b), g must divide b.")
|
51
|
+
|
52
|
+
if GMP::GMP_VERSION > "4.3.1"
|
53
|
+
assert_true(s.cmpabs(GMP::Z(1)) == 0 || (s*2).abs.cmpabs(temp2) <= 0, "GMP::Z#gcdext should work: #{s}.cmpabs(1)==0 or (#{s*2}.abs.cmpabs(#{temp2})<=0")
|
54
|
+
end
|
55
|
+
|
56
|
+
temp2 = s * a
|
57
|
+
temp2 = g - temp2
|
58
|
+
temp3 = temp2.tmod(b)
|
59
|
+
temp2 = temp2.tdiv(b)
|
60
|
+
assert_true(temp3.sgn == 0, "When [g, s, t] = a.gcdext(b), g must divide a.")
|
61
|
+
|
62
|
+
if GMP::GMP_VERSION > "4.3.1"
|
63
|
+
assert_true(temp2.cmpabs(GMP::Z(1)) == 0 || (temp2*2).abs.cmpabs(temp1) <= 0, "GMP::Z#gcdext should work...")
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def test_gcdext
|
68
|
+
reps = 200
|
69
|
+
#check_data
|
70
|
+
|
71
|
+
op2 = GMP::Z(GMP::GMP_NUMB_MAX)
|
72
|
+
op1 = op2 << 100
|
73
|
+
op1 += op2
|
74
|
+
op2 *= 2
|
75
|
+
one_test(op1, op2, nil, -1)
|
76
|
+
|
77
|
+
(0...reps).each do |i|
|
78
|
+
bs = @rand_state.urandomb(32)
|
79
|
+
size_range = bs.to_i % 17 + 2
|
80
|
+
bs = @rand_state.urandomb(size_range)
|
81
|
+
op1 = @rand_state.urandomb(bs.to_i + @min_operand_bitsize)
|
82
|
+
bs = @rand_state.urandomb(size_range)
|
83
|
+
op2 = @rand_state.urandomb(bs.to_i + @min_operand_bitsize)
|
84
|
+
|
85
|
+
bs = @rand_state.urandomb(8)
|
86
|
+
bsi = bs.to_i
|
87
|
+
|
88
|
+
if bsi & 0x3c == 4
|
89
|
+
op1 *= op2
|
90
|
+
elsif bsi & 0x3c == 8
|
91
|
+
op2 *= op1
|
92
|
+
end
|
93
|
+
|
94
|
+
op1.neg! if bsi & 1 != 0
|
95
|
+
op2.neg! if bsi & 2 != 0
|
96
|
+
|
97
|
+
one_test(op1, op2, nil, i)
|
98
|
+
|
99
|
+
op1 = GMP::Z(0)
|
100
|
+
bs = @rand_state.urandomb(32)
|
101
|
+
bs = @rand_state.urandomb(bs.to_i % 16 + 1)
|
102
|
+
op2 = @rand_state.rrandomb(bs.to_i)
|
103
|
+
op2 += 1
|
104
|
+
ref = op2
|
105
|
+
|
106
|
+
# UNTIL I CAN ACCESS GCD_DC_THRESHOLD
|
107
|
+
chain_len = 10
|
108
|
+
(1..chain_len).each do |j|
|
109
|
+
bs = @rand_state.urandomb(32)
|
110
|
+
bs = @rand_state.urandomb(bs.to_i % 12 + 1)
|
111
|
+
temp2 = @rand_state.rrandomb(bs.to_i + 1)
|
112
|
+
temp2 += 1
|
113
|
+
temp1 = op2 * temp2
|
114
|
+
op1 += temp1
|
115
|
+
|
116
|
+
bs = @rand_state.urandomb(32)
|
117
|
+
bs = @rand_state.urandomb(bs.to_i % 12 + 1)
|
118
|
+
temp2 = @rand_state.rrandomb(bs.to_i + 1)
|
119
|
+
temp2 += 1
|
120
|
+
temp1 = op1 * temp2
|
121
|
+
op2 += temp1
|
122
|
+
end
|
123
|
+
one_test(op1, op2, ref, i)
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require './test_helper'
|
2
|
+
|
3
|
+
class MPFR_TCONST_EULER < Test::Unit::TestCase
|
4
|
+
def setup
|
5
|
+
@rand_state = GMP::RandState.new
|
6
|
+
|
7
|
+
if GMP::MPFR_VERSION >= "3.0.0"
|
8
|
+
@mpfr_rnd_max = 5
|
9
|
+
else
|
10
|
+
@mpfr_rnd_max = 4
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_const_euler
|
15
|
+
prec = 53
|
16
|
+
|
17
|
+
y = GMP::F.const_euler(GMP::GMP_RNDN, 32)
|
18
|
+
z = GMP::F("0.10010011110001000110011111100011", 32, 2)
|
19
|
+
assert_equal(z, y, "Const Euler to precision 32 should be accurate.")
|
20
|
+
|
21
|
+
(2..200).each do |p|
|
22
|
+
z.prec= p
|
23
|
+
t = GMP::F(0, p)
|
24
|
+
yprec = p+10
|
25
|
+
|
26
|
+
(0...@mpfr_rnd_max).each do |rnd|
|
27
|
+
y.prec = yprec
|
28
|
+
GMP::F.const_euler(y, rnd)
|
29
|
+
err = rnd == GMP::GMP_RNDN ? yprec+1 : yprec
|
30
|
+
if y.can_round?(err, rnd, rnd, p)
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
data/test/tc_mpfr_functions.rb
CHANGED
@@ -1,13 +1,32 @@
|
|
1
1
|
class TC_MPFR_Functions < Test::Unit::TestCase
|
2
2
|
def setup
|
3
3
|
@a = GMP::F(1)
|
4
|
+
@b = GMP::F(2)
|
4
5
|
end
|
5
6
|
|
6
7
|
def test_const_existence
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
8
|
+
constants = ["const_log2", "const_pi", "const_euler", "const_catalan"]
|
9
|
+
|
10
|
+
constants.each do |c|
|
11
|
+
assert_nothing_raised("GMP::F##{c} can be called.") {
|
12
|
+
GMP::F.send(c)
|
13
|
+
}
|
14
|
+
assert_nothing_raised("GMP::F##{c} can be called w/ 1 arg: rounding_mode.") {
|
15
|
+
GMP::F.send(c, GMP::GMP_RNDN)
|
16
|
+
}
|
17
|
+
assert_nothing_raised("GMP::F##{c} can be called w/ 1 arg: rounding_mode.") {
|
18
|
+
GMP::F.send(c, GMP::GMP_RNDZ)
|
19
|
+
}
|
20
|
+
assert_nothing_raised("GMP::F##{c} can be called w/ 2 args: rounding_mode, prec.") {
|
21
|
+
GMP::F.send(c, GMP::GMP_RNDN, 32)
|
22
|
+
}
|
23
|
+
assert_nothing_raised("GMP::F##{c} can be called w/ 2 args: rounding_mode, prec.") {
|
24
|
+
GMP::F.send(c, GMP::GMP_RNDN, 128)
|
25
|
+
}
|
26
|
+
assert_nothing_raised("GMP::F##{c} can be called w/ 2 args: rounding_mode, prec.") {
|
27
|
+
GMP::F.send(c, GMP::GMP_RNDN, 200)
|
28
|
+
}
|
29
|
+
end
|
11
30
|
end
|
12
31
|
|
13
32
|
def test_function_existence
|
@@ -32,18 +51,19 @@ class TC_MPFR_Functions < Test::Unit::TestCase
|
|
32
51
|
assert_nothing_raised("GMP::F.cos should be callable.") { @a.cos }
|
33
52
|
assert_nothing_raised("GMP::F.sin should be callable.") { @a.sin }
|
34
53
|
assert_nothing_raised("GMP::F.tan should be callable.") { @a.tan }
|
54
|
+
assert_nothing_raised("GMP::F.sin_cos should be callable.") { @a.sin_cos }
|
35
55
|
assert_nothing_raised("GMP::F.sec should be callable.") { @a.sec }
|
36
56
|
assert_nothing_raised("GMP::F.csc should be callable.") { @a.csc }
|
37
57
|
assert_nothing_raised("GMP::F.cot should be callable.") { @a.cot }
|
38
|
-
|
39
58
|
assert_nothing_raised("GMP::F.acos should be callable.") { @a.acos }
|
40
59
|
assert_nothing_raised("GMP::F.asin should be callable.") { @a.asin }
|
41
60
|
assert_nothing_raised("GMP::F.atan should be callable.") { @a.atan }
|
61
|
+
assert_nothing_raised("GMP::F.atan2 should be callable.") { @a.atan2(@b) }
|
42
62
|
|
43
63
|
assert_nothing_raised("GMP::F.cosh should be callable.") { @a.cosh }
|
44
64
|
assert_nothing_raised("GMP::F.sinh should be callable.") { @a.sinh }
|
45
65
|
assert_nothing_raised("GMP::F.tanh should be callable.") { @a.tanh }
|
46
|
-
|
66
|
+
assert_nothing_raised("GMP::F.sinh_cosh should be callable.") { @a.sinh_cosh }
|
47
67
|
assert_nothing_raised("GMP::F.sech should be callable.") { @a.sech }
|
48
68
|
assert_nothing_raised("GMP::F.csch should be callable.") { @a.csch }
|
49
69
|
assert_nothing_raised("GMP::F.coth should be callable.") { @a.coth }
|
@@ -76,26 +96,37 @@ class TC_MPFR_Functions < Test::Unit::TestCase
|
|
76
96
|
assert_nothing_raised("GMP::F.yn should be callable.") { @a.yn(0) }
|
77
97
|
assert_nothing_raised("GMP::F.yn should be callable.") { @a.yn(1) }
|
78
98
|
assert_nothing_raised("GMP::F.yn should be callable.") { @a.yn(2) }
|
99
|
+
|
100
|
+
assert_nothing_raised("GMP::F.agm should be callable.") { @a.agm(@b) }
|
101
|
+
assert_nothing_raised("GMP::F.hypot should be callable.") { @a.hypot(@b) }
|
79
102
|
end
|
80
103
|
|
81
104
|
def test_function_parameters
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
105
|
+
single_functions = [:sqrt, :rec_sqrt, :cbrt,
|
106
|
+
:log, :log2, :log10, :exp, :exp2, :exp10,
|
107
|
+
:cos, :sin, :tan, :sin_cos, :sec, :csc, :cot,
|
108
|
+
:acos, :asin, :atan,
|
109
|
+
:cosh, :sinh, :tanh, :sech, :csch, :coth,
|
110
|
+
:acosh, :asinh, :atanh,
|
111
|
+
:log1p, :expm1, :eint, :li2, :gamma, :lngamma,
|
112
|
+
:zeta, :erf, :erfc,
|
113
|
+
:j0, :j1, :y0, :y1
|
114
|
+
]
|
115
|
+
single_functions += [:digamma] if GMP::MPFR_VERSION >= "3.0.0"
|
116
|
+
double_functions = [:sin_cos, :sinh_cosh]
|
117
|
+
single_mpf_functions = [:atan2, :agm, :hypot]
|
92
118
|
|
93
|
-
|
119
|
+
(single_functions + double_functions).each do |f|
|
94
120
|
assert_nothing_raised("GMP::F.#{f} can be called w/ 1 arg: rounding_mode.") { @a.send(f, GMP::GMP_RNDN) }
|
95
121
|
assert_nothing_raised("GMP::F.#{f} can be called w/ 1 arg: rounding_mode.") { @a.send(f, GMP::GMP_RNDZ) }
|
96
122
|
assert_nothing_raised("GMP::F.#{f} can be called w/ 2 args: rounding_mode, prec.") { @a.send(f, GMP::GMP_RNDN, 32) }
|
97
123
|
assert_nothing_raised("GMP::F.#{f} can be called w/ 2 args: rounding_mode, prec.") { @a.send(f, GMP::GMP_RNDN, 128) }
|
98
124
|
assert_nothing_raised("GMP::F.#{f} can be called w/ 2 args: rounding_mode, prec.") { @a.send(f, GMP::GMP_RNDN, 200) }
|
99
125
|
end
|
126
|
+
double_functions.each do |f|
|
127
|
+
assert_nothing_raised("GMP::F.#{f} can be called w/ 3 args: rounding_mode, prec, prec.") { @a.send(f, GMP::GMP_RNDN, 64, 64) }
|
128
|
+
assert_nothing_raised("GMP::F.#{f} can be called w/ 3 args: rounding_mode, prec, prec.") { @a.send(f, GMP::GMP_RNDN, 128, 64) }
|
129
|
+
assert_nothing_raised("GMP::F.#{f} can be called w/ 3 args: rounding_mode, prec, prec.") { @a.send(f, GMP::GMP_RNDN, 64, 128) }
|
130
|
+
end
|
100
131
|
end
|
101
132
|
end
|