gmp 0.2.1 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +8 -0
- data/README.rdoc +8 -8
- data/ext/gmpf.c +24 -13
- data/ext/gmpq.c +5 -0
- data/ext/gmpz.c +429 -344
- data/ext/ruby_gmp.h +10 -8
- data/manual.pdf +0 -0
- data/manual.tex +167 -53
- data/test/README +1 -1
- data/test/tc_fib_fac_nextprime.rb +6 -6
- data/test/tc_z_jac_leg_rem.rb +73 -0
- data/test/unit_tests.rb +1 -0
- metadata +3 -2
data/CHANGELOG
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
0.2.2:
|
2
|
+
* GMP::Z.jacobi and GPM::Z#jacobi work and are tested.
|
3
|
+
* GMP::Z.legendre works and is tested.
|
4
|
+
* GMP::Z.next_prime is an alias for GMP::Z.nextprime.
|
5
|
+
* GMP::Z.next_prime! is an alias for GMP::Z.nextprime!.
|
6
|
+
* GMP::Z.remove works as it is supposed to.
|
7
|
+
* PDF documentation is extended.
|
8
|
+
|
1
9
|
0.2.1:
|
2
10
|
* Got GMP::F(Fixnum) working, (I think it already was).
|
3
11
|
* More and more documentation in PDF.
|
data/README.rdoc
CHANGED
@@ -47,7 +47,7 @@ paragraph at http://gmplib.org/#WHAT :
|
|
47
47
|
contributors to sign paperwork where they allow us to distribute their work."
|
48
48
|
|
49
49
|
Only GMP 4 or newer is supported. The following environments have been tested by me:
|
50
|
-
gmp gem 0.
|
50
|
+
gmp gem 0.2.2 on:
|
51
51
|
+-------------------------------------+-------------------+-----------+
|
52
52
|
| Platform | Ruby | GMP |
|
53
53
|
+-------------------------------------+-------------------+-----------+
|
@@ -77,8 +77,8 @@ Constructors can take following arguments:
|
|
77
77
|
|
78
78
|
GMP::Z.new()
|
79
79
|
GMP::Z.new(GMP::Z)
|
80
|
-
GMP::Z.new(
|
81
|
-
GMP::Z.new(
|
80
|
+
GMP::Z.new(Fixnum)
|
81
|
+
GMP::Z.new(Bignum)
|
82
82
|
GMP::Z.new(String)
|
83
83
|
GMP::Q.new()
|
84
84
|
GMP::Q.new(GMP::Q)
|
@@ -91,14 +91,14 @@ Constructors can take following arguments:
|
|
91
91
|
GMP::F.new(GMP::F)
|
92
92
|
GMP::F.new(GMP::F, precision)
|
93
93
|
GMP::F.new(String, precision=0)
|
94
|
-
GMP::F.new(
|
95
|
-
GMP::F.new(
|
94
|
+
GMP::F.new(Fixnum, precision=0)
|
95
|
+
GMP::F.new(Bignum, precision=0)
|
96
96
|
GMP::F.new(Float, precision=0)
|
97
97
|
|
98
98
|
You can also call them as:
|
99
|
-
|
100
|
-
|
101
|
-
|
99
|
+
GMP.Z(args)
|
100
|
+
GMP.Q(args)
|
101
|
+
GMP.F(args)
|
102
102
|
|
103
103
|
=Methods
|
104
104
|
|
data/ext/gmpf.c
CHANGED
@@ -10,6 +10,17 @@
|
|
10
10
|
* Instances of this class can store variables of the type mpf_t. This class
|
11
11
|
* also contains many methods that act as the functions for mpf_t variables,
|
12
12
|
* as well as a few methods that attempt to make this library more Ruby-ish.
|
13
|
+
*
|
14
|
+
* The following list is just a simple checklist for me, really. A better
|
15
|
+
* reference should be found in the rdocs.
|
16
|
+
*
|
17
|
+
* Ruby method C Extension function GMP function
|
18
|
+
* to_d r_gmpf_to_d mpf_get_d
|
19
|
+
* to_s r_gmpf_to_s mpf_get_s
|
20
|
+
* + r_gmpf_add mpf_add
|
21
|
+
* - r_gmpf_sub mpf_sub
|
22
|
+
* * r_gmpf_mul mpf_mul
|
23
|
+
* / r_gmpf_div mpf_div
|
13
24
|
*/
|
14
25
|
|
15
26
|
/**********************************************************************
|
@@ -379,33 +390,33 @@ VALUE r_gmpf_div(VALUE self, VALUE arg)
|
|
379
390
|
mpf_get_struct_prec (self, self_val, prec);
|
380
391
|
|
381
392
|
if (GMPF_P(arg)) {
|
382
|
-
mpf_get_struct
|
393
|
+
mpf_get_struct(arg, arg_val_f);
|
383
394
|
prec_max(prec, arg_val_f);
|
384
395
|
mpf_make_struct_init(res, res_val, prec);
|
385
396
|
mpf_div(res_val, self_val, arg_val_f);
|
386
397
|
} else if (GMPQ_P(arg)) {
|
387
|
-
mpq_get_struct
|
398
|
+
mpq_get_struct(arg, arg_val_q);
|
388
399
|
mpf_make_struct_init(res, res_val, prec);
|
389
|
-
mpf_set_q
|
390
|
-
mpf_div
|
400
|
+
mpf_set_q(res_val, arg_val_q);
|
401
|
+
mpf_div(res_val, self_val, res_val);
|
391
402
|
} else if (GMPZ_P(arg)) {
|
392
|
-
mpz_get_struct
|
403
|
+
mpz_get_struct(arg, arg_val_z);
|
393
404
|
mpf_make_struct_init(res, res_val, prec);
|
394
|
-
mpf_set_z
|
395
|
-
mpf_div
|
405
|
+
mpf_set_z(res_val, arg_val_z);
|
406
|
+
mpf_div(res_val, self_val, res_val);
|
396
407
|
} else if (FLOAT_P(arg)) {
|
397
408
|
mpf_make_struct_init(res, res_val, prec);
|
398
|
-
mpf_set_d
|
399
|
-
mpf_div
|
409
|
+
mpf_set_d(res_val, NUM2DBL(arg));
|
410
|
+
mpf_div(res_val, self_val, res_val);
|
400
411
|
} else if (FIXNUM_P(arg)) { // _ui with sign control instead ?
|
401
412
|
mpf_make_struct_init(res, res_val, prec);
|
402
|
-
mpf_set_si
|
403
|
-
mpf_div
|
413
|
+
mpf_set_si(res_val, FIX2INT(arg));
|
414
|
+
mpf_div(res_val, self_val, res_val);
|
404
415
|
} else if (BIGNUM_P(arg)) {
|
405
416
|
mpz_temp_from_bignum(arg_val_z, arg);
|
406
417
|
mpf_make_struct_init(res, res_val, prec);
|
407
|
-
mpf_set_z
|
408
|
-
mpf_div
|
418
|
+
mpf_set_z(res_val, arg_val_z);
|
419
|
+
mpf_div(res_val, self_val, res_val);
|
409
420
|
mpz_temp_free(arg_val_z);
|
410
421
|
} else {
|
411
422
|
typeerror(ZQFXBD);
|
data/ext/gmpq.c
CHANGED
@@ -21,6 +21,11 @@
|
|
21
21
|
* sub r_gmpq_sub mpq_sub
|
22
22
|
* mul r_gmpq_mul mpq_mul
|
23
23
|
* div r_gmpq_div mpq_div
|
24
|
+
* -@ r_gmpq_neg mpq_neg
|
25
|
+
* neg r_gmpq_neg mpq_neg
|
26
|
+
* neg! r_gmpq_neg_self mpq_neg
|
27
|
+
* abs r_gmpq_abs mpq_abs
|
28
|
+
* abs! r_gmpq_abs_self mpq_abs
|
24
29
|
*/
|
25
30
|
|
26
31
|
/**********************************************************************
|
data/ext/gmpz.c
CHANGED
@@ -14,42 +14,52 @@
|
|
14
14
|
* The following list is just a simple checklist for me, really. A better
|
15
15
|
* reference should be found in the rdocs.
|
16
16
|
*
|
17
|
-
* Ruby method
|
18
|
-
* to_d
|
19
|
-
* to_i
|
20
|
-
* to_s
|
21
|
-
* +
|
22
|
-
* add!
|
23
|
-
* -
|
24
|
-
* sub!
|
25
|
-
* *
|
26
|
-
* /
|
27
|
-
* tdiv
|
28
|
-
* tmod
|
29
|
-
* fdiv
|
30
|
-
* fmod
|
31
|
-
* cdiv
|
32
|
-
* cmod
|
33
|
-
* -@
|
34
|
-
* neg
|
35
|
-
* neg!
|
36
|
-
* abs
|
37
|
-
* abs!
|
38
|
-
*
|
39
|
-
*
|
40
|
-
*
|
41
|
-
*
|
42
|
-
*
|
43
|
-
*
|
44
|
-
*
|
45
|
-
*
|
46
|
-
*
|
47
|
-
*
|
48
|
-
*
|
49
|
-
*
|
50
|
-
*
|
51
|
-
*
|
52
|
-
*
|
17
|
+
* Ruby method C Extension function GMP function
|
18
|
+
* to_d r_gmpz_to_d mpz_get_d
|
19
|
+
* to_i r_gmpz_to_i mpz_get_i
|
20
|
+
* to_s r_gmpz_to_s mpz_get_s
|
21
|
+
* + r_gmpz_add mpz_add
|
22
|
+
* add! r_gmpz_add_self mpz_add
|
23
|
+
* - r_gmpz_sub mpz_sub
|
24
|
+
* sub! r_gmpz_sub_self mpz_sub
|
25
|
+
* * r_gmpz_mul mpz_mul
|
26
|
+
* / r_gmpz_div ...
|
27
|
+
* tdiv r_gmpz_tdiv mpz_tdiv_q
|
28
|
+
* tmod r_gmpz_tmod mpz_tdiv_r
|
29
|
+
* fdiv r_gmpz_fdiv mpz_fdiv_q
|
30
|
+
* fmod r_gmpz_fmod mpz_fdiv_r
|
31
|
+
* cdiv r_gmpz_cdiv mpz_cdiv_q
|
32
|
+
* cmod r_gmpz_cmod mpz_cdiv_r
|
33
|
+
* -@ r_gmpz_neg mpz_neg
|
34
|
+
* neg r_gmpz_neg mpz_neg
|
35
|
+
* neg! r_gmpz_neg_self mpz_neg
|
36
|
+
* abs r_gmpz_abs mpz_abs
|
37
|
+
* abs! r_gmpz_abs_self mpz_abs
|
38
|
+
* ** r_gmpz_pow mpz_pow_ui
|
39
|
+
* powmod r_gmpz_powm mpz_powm
|
40
|
+
* root r_gmpz_root mpz_root
|
41
|
+
* sqrt r_gmpz_sqrt mpz_sqrt
|
42
|
+
* sqrt! r_gmpz_sqrt_self mpz_sqrt
|
43
|
+
* sqrtrem r_gmpz_sqrtrem mpz_sqrtrem
|
44
|
+
* power? r_gmpz_is_power mpz_perfect_power_p
|
45
|
+
* square? r_gmpz_is_square mpz_perfect_square_p
|
46
|
+
* probab_prime? r_gmpz_is_probab_prime mpz_probab_prime_p
|
47
|
+
* nextprime r_gmpz_nextprime mpz_nextprime
|
48
|
+
* nextprime! r_gmpz_nextprime_self mpz_nextprime
|
49
|
+
* jacobi r_gmpz_jacobi mpz_jacobi
|
50
|
+
* #jacobi r_gmpzsg_jacobi mpz_jacobi
|
51
|
+
* legendre r_gmpz_legendre mpz_legendre
|
52
|
+
* remove r_gmpz_remove mpz_remove
|
53
|
+
* fac r_gmpz_fac mpz_fac_ui
|
54
|
+
* fib r_gmpz_fib mpz_fib_ui
|
55
|
+
* com r_gmpz_com mpz_com
|
56
|
+
* com! r_gmpz_com_self mpz_com
|
57
|
+
* []= r_gmpz_setbit mpz_setbit
|
58
|
+
* [] r_gmpz_getbit mpz_tstbit
|
59
|
+
* scan0 r_gmpz_scan0 mpz_scan0
|
60
|
+
* scan1 r_gmpz_scan1 mpz_scan1
|
61
|
+
* even? r_gmpz_is_even mpz_even
|
62
|
+
* odd? r_gmpz_is_odd mpz_odd
|
53
63
|
* ...
|
54
64
|
*/
|
55
65
|
|
@@ -78,7 +88,7 @@ static VALUE r_gmpz_##fname##_self(VALUE self) \
|
|
78
88
|
MP_INT *self_val; \
|
79
89
|
mpz_get_struct(self, self_val); \
|
80
90
|
mpz_fname(self_val, self_val); \
|
81
|
-
return
|
91
|
+
return self; \
|
82
92
|
}
|
83
93
|
|
84
94
|
#define DEFUN_INT_F_UL(fname,mpz_fname,argname) \
|
@@ -641,6 +651,19 @@ VALUE r_gmpz_mul(VALUE self, VALUE arg)
|
|
641
651
|
return res;
|
642
652
|
}
|
643
653
|
|
654
|
+
/*
|
655
|
+
* Document-method: <<
|
656
|
+
*
|
657
|
+
* call-seq:
|
658
|
+
* integer << n
|
659
|
+
*
|
660
|
+
* From the GMP Manual:
|
661
|
+
*
|
662
|
+
* Returns +integer+ times 2 raised to +n+. This operation can also be defined
|
663
|
+
* as a left shift by +n+ bits.
|
664
|
+
*/
|
665
|
+
DEFUN_INT_F_UL(shl,mpz_mul_2exp,"shift size")
|
666
|
+
|
644
667
|
/*
|
645
668
|
* Document-method: neg
|
646
669
|
*
|
@@ -866,6 +889,90 @@ DEFUN_INT_DIV(cmod, mpz_cdiv_r)
|
|
866
889
|
* Integer Exponentiation *
|
867
890
|
**********************************************************************/
|
868
891
|
|
892
|
+
/*
|
893
|
+
* Document-method: **
|
894
|
+
*
|
895
|
+
* call-seq:
|
896
|
+
* integer ** exp
|
897
|
+
*
|
898
|
+
* From the GMP Manual:
|
899
|
+
*
|
900
|
+
* Returns +integer+ raised to +exp+. The case 0^0 yields 1.
|
901
|
+
*/
|
902
|
+
DEFUN_INT_F_UL(pow,mpz_pow_ui,"exponent")
|
903
|
+
|
904
|
+
/*
|
905
|
+
* call-seq:
|
906
|
+
* integer.powmod(exp, mod)
|
907
|
+
*
|
908
|
+
* From the GMP Manual:
|
909
|
+
*
|
910
|
+
* Returns +integer+ raised to +exp+ modulo +mod+.
|
911
|
+
*
|
912
|
+
* Negative +exp+ is supported if an inverse <tt>integer^-1</tt> mod
|
913
|
+
* <tt>mod</tt> exists. If an inverse doesn't exist then a divide by zero is
|
914
|
+
* raised.
|
915
|
+
*/
|
916
|
+
VALUE r_gmpz_powm(VALUE self, VALUE exp, VALUE mod)
|
917
|
+
{
|
918
|
+
MP_INT *self_val, *res_val, *mod_val, *exp_val;
|
919
|
+
VALUE res;
|
920
|
+
int free_mod_val = 0;
|
921
|
+
|
922
|
+
if (GMPZ_P(mod)) {
|
923
|
+
mpz_get_struct(mod, mod_val);
|
924
|
+
if (mpz_sgn(mod_val) <= 0) {
|
925
|
+
rb_raise(rb_eRangeError, "modulus must be positive");
|
926
|
+
}
|
927
|
+
} else if (FIXNUM_P(mod)) {
|
928
|
+
if (FIX2INT(mod) <= 0) {
|
929
|
+
rb_raise(rb_eRangeError, "modulus must be positive");
|
930
|
+
}
|
931
|
+
mpz_temp_alloc(mod_val);
|
932
|
+
mpz_init_set_ui(mod_val, FIX2INT(mod));
|
933
|
+
free_mod_val = 1;
|
934
|
+
} else if (BIGNUM_P(mod)) {
|
935
|
+
mpz_temp_from_bignum(mod_val, mod);
|
936
|
+
if (mpz_sgn(mod_val) <= 0) {
|
937
|
+
mpz_temp_free(mod_val);
|
938
|
+
rb_raise(rb_eRangeError, "modulus must be positive");
|
939
|
+
}
|
940
|
+
free_mod_val = 1;
|
941
|
+
} else {
|
942
|
+
typeerror_as(ZXB, "modulus");
|
943
|
+
}
|
944
|
+
mpz_make_struct_init(res, res_val);
|
945
|
+
mpz_get_struct(self, self_val);
|
946
|
+
|
947
|
+
if (GMPZ_P(exp)) {
|
948
|
+
mpz_get_struct(exp, exp_val);
|
949
|
+
if (mpz_sgn(mod_val) < 0) {
|
950
|
+
rb_raise(rb_eRangeError, "exponent must be nonnegative");
|
951
|
+
}
|
952
|
+
mpz_powm(res_val, self_val, exp_val, mod_val);
|
953
|
+
} else if (FIXNUM_P(exp)) {
|
954
|
+
if (FIX2INT(exp) < 0)
|
955
|
+
{
|
956
|
+
if (free_mod_val)
|
957
|
+
mpz_temp_free(mod_val);
|
958
|
+
rb_raise(rb_eRangeError, "exponent must be nonnegative");
|
959
|
+
}
|
960
|
+
mpz_powm_ui(res_val, self_val, FIX2INT(exp), mod_val);
|
961
|
+
} else if (BIGNUM_P(exp)) {
|
962
|
+
mpz_temp_from_bignum(exp_val, exp);
|
963
|
+
mpz_powm(res_val, self_val, exp_val, mod_val);
|
964
|
+
mpz_temp_free(exp_val);
|
965
|
+
} else {
|
966
|
+
if (free_mod_val)
|
967
|
+
mpz_temp_free(mod_val);
|
968
|
+
typeerror_as(ZXB, "exponent");
|
969
|
+
}
|
970
|
+
if (free_mod_val)
|
971
|
+
mpz_temp_free(mod_val);
|
972
|
+
return res;
|
973
|
+
}
|
974
|
+
|
975
|
+
|
869
976
|
/**********************************************************************
|
870
977
|
* Integer Roots *
|
871
978
|
**********************************************************************/
|
@@ -928,11 +1035,227 @@ static VALUE r_gmpz_sqrtrem(VALUE self)
|
|
928
1035
|
return rb_assoc_new(sqrt, rem);
|
929
1036
|
}
|
930
1037
|
|
1038
|
+
/*
|
1039
|
+
* Document-method: power?
|
1040
|
+
*
|
1041
|
+
* call-seq:
|
1042
|
+
* integer.power?
|
1043
|
+
*
|
1044
|
+
* From the GMP Manual:
|
1045
|
+
*
|
1046
|
+
* Returns true if integer is a perfect power, i.e., if there exist integers a
|
1047
|
+
* and b, with b>1, such that integer equals a raised to the power b.
|
1048
|
+
*
|
1049
|
+
* Under this definition both 0 and 1 are considered to be perfect powers.
|
1050
|
+
* Negative values of integers are accepted, but of course can only be odd
|
1051
|
+
* perfect powers.
|
1052
|
+
*/
|
1053
|
+
DEFUN_INT_COND_P(is_power,mpz_perfect_power_p)
|
1054
|
+
/*
|
1055
|
+
* Document-method: square?
|
1056
|
+
*
|
1057
|
+
* call-seq:
|
1058
|
+
* integer.square?
|
1059
|
+
*
|
1060
|
+
* From the GMP Manual:
|
1061
|
+
*
|
1062
|
+
* Returns true if integer is a perfect square, i.e., if the square root of
|
1063
|
+
* integer is an integer. Under this definition both 0 and 1 are considered to
|
1064
|
+
* be perfect squares.
|
1065
|
+
*/
|
1066
|
+
DEFUN_INT_COND_P(is_square,mpz_perfect_square_p)
|
1067
|
+
|
931
1068
|
|
932
1069
|
/**********************************************************************
|
933
1070
|
* Number Theoretic Functions *
|
934
1071
|
**********************************************************************/
|
935
1072
|
|
1073
|
+
/*
|
1074
|
+
* call-seq: probab_prime?(reps = 5)
|
1075
|
+
*
|
1076
|
+
* Determine whether +n+ is prime. Returns 2 if +n+ is definitely prime,
|
1077
|
+
* returns 1 if +n+ is probably prime (without being certain), or returns 0 if
|
1078
|
+
* +n+ is definitely composite.
|
1079
|
+
*
|
1080
|
+
* This function does some trial divisions, then some Miller-Rabin
|
1081
|
+
* probabilistic primality tests. +reps+ controls how many such tests are done,
|
1082
|
+
* 5 to 10 is a reasonable number, more will reduce the chances of a composite
|
1083
|
+
* being returned as "probably prime".
|
1084
|
+
*
|
1085
|
+
* Miller-Rabin and similar tests can be more properly called compositeness
|
1086
|
+
* tests. Numbers which fail are known to be composite but those which pass
|
1087
|
+
* might be prime or might be composite. Only a few composites pass, hence
|
1088
|
+
* those which pass are considered probably prime.
|
1089
|
+
*/
|
1090
|
+
VALUE r_gmpz_is_probab_prime(int argc, VALUE* argv, VALUE self)
|
1091
|
+
{
|
1092
|
+
MP_INT *self_val;
|
1093
|
+
int reps_val;
|
1094
|
+
VALUE reps;
|
1095
|
+
mpz_get_struct(self, self_val);
|
1096
|
+
rb_scan_args(argc, argv, "01", &reps);
|
1097
|
+
if(NIL_P(reps)){
|
1098
|
+
reps = INT2FIX(5);
|
1099
|
+
}
|
1100
|
+
if (FIXNUM_P(reps)) {
|
1101
|
+
reps_val = FIX2INT (reps);
|
1102
|
+
} else {
|
1103
|
+
typeerror_as(X, "reps");
|
1104
|
+
}
|
1105
|
+
return INT2FIX(mpz_probab_prime_p(self_val, reps_val));
|
1106
|
+
}
|
1107
|
+
|
1108
|
+
/*
|
1109
|
+
* Document-method: nextprime
|
1110
|
+
*
|
1111
|
+
* call-seq:
|
1112
|
+
* integer.nextprime
|
1113
|
+
* integer.next_prime
|
1114
|
+
*
|
1115
|
+
* From the GMP Manual:
|
1116
|
+
*
|
1117
|
+
* Returns the next prime greater than +integer+.
|
1118
|
+
*
|
1119
|
+
* This function uses a probabilistic algorithm to identify primes. For
|
1120
|
+
* practical purposes it's adequate, the chance of a composite passing will be
|
1121
|
+
* extremely small.
|
1122
|
+
*/
|
1123
|
+
/*
|
1124
|
+
* Document-method: nextprime!
|
1125
|
+
*
|
1126
|
+
* call-seq:
|
1127
|
+
* integer.nextprime!
|
1128
|
+
* integer.next_prime!
|
1129
|
+
*
|
1130
|
+
* From the GMP Manual:
|
1131
|
+
*
|
1132
|
+
* Sets +integer+ to the next prime greater than +integer+.
|
1133
|
+
*
|
1134
|
+
* This function uses a probabilistic algorithm to identify primes. For
|
1135
|
+
* practical purposes it's adequate, the chance of a composite passing will be
|
1136
|
+
* extremely small.
|
1137
|
+
*/
|
1138
|
+
DEFUN_INT2INT(nextprime, mpz_nextprime)
|
1139
|
+
|
1140
|
+
/*
|
1141
|
+
* Document-method: jacobi
|
1142
|
+
*
|
1143
|
+
* call-seq:
|
1144
|
+
* a.jacobi(b)
|
1145
|
+
*
|
1146
|
+
* From the GMP Manual:
|
1147
|
+
*
|
1148
|
+
* Calculate the Jacobi symbol <tt>(a/b)</tt>. This is defined only for +b+
|
1149
|
+
* odd and positive.
|
1150
|
+
*/
|
1151
|
+
VALUE r_gmpz_jacobi(VALUE self, VALUE b)
|
1152
|
+
{
|
1153
|
+
MP_INT *self_val, *b_val;
|
1154
|
+
int res_val;
|
1155
|
+
mpz_get_struct(self, self_val);
|
1156
|
+
mpz_get_struct( b, b_val);
|
1157
|
+
if (mpz_sgn(b_val) != 1)
|
1158
|
+
rb_raise(rb_eRangeError, "Cannot take Jacobi symbol (a/b) where b is non-positive.");
|
1159
|
+
if (mpz_even_p(b_val))
|
1160
|
+
rb_raise(rb_eRangeError, "Cannot take Jacobi symbol (a/b) where b is even.");
|
1161
|
+
res_val = mpz_jacobi(self_val, b_val);
|
1162
|
+
return INT2FIX(res_val);
|
1163
|
+
}
|
1164
|
+
|
1165
|
+
/*
|
1166
|
+
* Document-method: GMP::Z.jacobi
|
1167
|
+
*
|
1168
|
+
* call-seq:
|
1169
|
+
* GMP::Z.jacobi(a, b)
|
1170
|
+
*
|
1171
|
+
* From the GMP Manual:
|
1172
|
+
*
|
1173
|
+
* Calculate the Jacobi symbol <tt>(a/b)</tt>. This is defined only for +b+
|
1174
|
+
* odd and positive.
|
1175
|
+
*/
|
1176
|
+
VALUE r_gmpzsg_jacobi(VALUE klass, VALUE a, VALUE b)
|
1177
|
+
{
|
1178
|
+
MP_INT *a_val, *b_val;
|
1179
|
+
int res_val;
|
1180
|
+
int free_a_val = 0;
|
1181
|
+
int free_b_val = 0;
|
1182
|
+
(void)klass;
|
1183
|
+
|
1184
|
+
if (GMPZ_P(a)) {
|
1185
|
+
mpz_get_struct(a, a_val);
|
1186
|
+
} else if (FIXNUM_P(a)) {
|
1187
|
+
mpz_temp_alloc(a_val);
|
1188
|
+
mpz_init_set_ui(a_val, FIX2INT(a));
|
1189
|
+
free_a_val = 1;
|
1190
|
+
} else if (BIGNUM_P(a)) {
|
1191
|
+
mpz_temp_from_bignum(a_val, a);
|
1192
|
+
free_a_val = 1;
|
1193
|
+
} else {
|
1194
|
+
typeerror_as(ZXB, "a");
|
1195
|
+
}
|
1196
|
+
|
1197
|
+
if (GMPZ_P(b)) {
|
1198
|
+
mpz_get_struct(b, b_val);
|
1199
|
+
if (mpz_sgn(b_val) != 1)
|
1200
|
+
rb_raise(rb_eRangeError, "Cannot take Jacobi symbol (a/b) where b is non-positive.");
|
1201
|
+
if (mpz_even_p(b_val))
|
1202
|
+
rb_raise(rb_eRangeError, "Cannot take Jacobi symbol (a/b) where b is even.");
|
1203
|
+
} else if (FIXNUM_P(b)) {
|
1204
|
+
if (FIX2INT(b) <= 0)
|
1205
|
+
rb_raise(rb_eRangeError, "Cannot take Jacobi symbol (a/b) where b is non-positive.");
|
1206
|
+
if (FIX2INT(b) % 2 == 0)
|
1207
|
+
rb_raise(rb_eRangeError, "Cannot take Jacobi symbol (a/b) where b is even.");
|
1208
|
+
mpz_temp_alloc(b_val);
|
1209
|
+
mpz_init_set_ui(b_val, FIX2INT(b));
|
1210
|
+
free_b_val = 1;
|
1211
|
+
} else if (BIGNUM_P(b)) {
|
1212
|
+
mpz_temp_from_bignum(b_val, b);
|
1213
|
+
if (mpz_sgn(b_val) != 1) {
|
1214
|
+
mpz_temp_free(b_val);
|
1215
|
+
rb_raise(rb_eRangeError, "Cannot take Jacobi symbol (a/b) where b is non-positive.");
|
1216
|
+
}
|
1217
|
+
if (mpz_even_p(b_val)) {
|
1218
|
+
mpz_temp_free(b_val);
|
1219
|
+
rb_raise(rb_eRangeError, "Cannot take Jacobi symbol (a/b) where b is even.");
|
1220
|
+
}
|
1221
|
+
free_b_val = 1;
|
1222
|
+
} else {
|
1223
|
+
typeerror_as(ZXB, "b");
|
1224
|
+
}
|
1225
|
+
|
1226
|
+
res_val = mpz_jacobi(a_val, b_val);
|
1227
|
+
if (free_a_val) { mpz_temp_free(a_val); }
|
1228
|
+
if (free_b_val) { mpz_temp_free(b_val); }
|
1229
|
+
return INT2FIX(res_val);
|
1230
|
+
}
|
1231
|
+
|
1232
|
+
/*
|
1233
|
+
* Document-method: legendre
|
1234
|
+
*
|
1235
|
+
* call-seq:
|
1236
|
+
* a.legendre(p)
|
1237
|
+
*
|
1238
|
+
* From the GMP Manual:
|
1239
|
+
*
|
1240
|
+
* Calculate the Legendre symbol <tt>(a/p)</tt>. This is defined only for +p+
|
1241
|
+
* an odd positive prime, and for such +p+ it's identical to the Jacobi symbol.
|
1242
|
+
*/
|
1243
|
+
VALUE r_gmpz_legendre(VALUE self, VALUE p)
|
1244
|
+
{
|
1245
|
+
MP_INT *self_val, *p_val;
|
1246
|
+
int res_val;
|
1247
|
+
mpz_get_struct(self, self_val);
|
1248
|
+
mpz_get_struct( p, p_val);
|
1249
|
+
if (mpz_sgn(p_val) != 1)
|
1250
|
+
rb_raise(rb_eRangeError, "Cannot take Legendre symbol (a/p) where p is non-positive.");
|
1251
|
+
if (mpz_even_p(p_val))
|
1252
|
+
rb_raise(rb_eRangeError, "Cannot take Legendre symbol (a/p) where p is even.");
|
1253
|
+
if (mpz_probab_prime_p(p_val, 5) == 0)
|
1254
|
+
rb_raise(rb_eRangeError, "Cannot take Legendre symbol (a/p) where p is composite.");
|
1255
|
+
res_val = mpz_legendre(self_val, p_val);
|
1256
|
+
return INT2FIX(res_val);
|
1257
|
+
}
|
1258
|
+
|
936
1259
|
/*
|
937
1260
|
* Document-method: remove
|
938
1261
|
*
|
@@ -948,9 +1271,10 @@ VALUE r_gmpz_remove(VALUE self, VALUE arg)
|
|
948
1271
|
{
|
949
1272
|
MP_INT *self_val, *arg_val, *res_val;
|
950
1273
|
VALUE res;
|
1274
|
+
int removed_val;
|
951
1275
|
int free_arg_val = 0;
|
952
1276
|
|
953
|
-
mpz_get_struct(self,self_val);
|
1277
|
+
mpz_get_struct(self, self_val);
|
954
1278
|
|
955
1279
|
if (GMPZ_P(arg)) {
|
956
1280
|
mpz_get_struct(arg,arg_val);
|
@@ -964,20 +1288,20 @@ VALUE r_gmpz_remove(VALUE self, VALUE arg)
|
|
964
1288
|
} else if (BIGNUM_P(arg)) {
|
965
1289
|
mpz_temp_from_bignum(arg_val, arg);
|
966
1290
|
if (mpz_sgn(arg_val) != 1) {
|
967
|
-
mpz_temp_free
|
1291
|
+
mpz_temp_free(arg_val);
|
968
1292
|
rb_raise(rb_eRangeError, "argument must be positive");
|
969
1293
|
}
|
970
1294
|
} else {
|
971
1295
|
typeerror(ZXB);
|
972
1296
|
}
|
973
1297
|
|
974
|
-
mpz_make_struct_init
|
975
|
-
mpz_remove
|
1298
|
+
mpz_make_struct_init(res, res_val);
|
1299
|
+
removed_val = mpz_remove(res_val, self_val, arg_val);
|
976
1300
|
|
977
1301
|
if (free_arg_val)
|
978
1302
|
mpz_temp_free(arg_val);
|
979
1303
|
|
980
|
-
return res;
|
1304
|
+
return rb_assoc_new(res, INT2FIX(removed_val));
|
981
1305
|
}
|
982
1306
|
|
983
1307
|
/*
|
@@ -1190,110 +1514,6 @@ VALUE r_gmpz_scan1(VALUE self, VALUE bitnr)
|
|
1190
1514
|
return INT2FIX(mpz_scan1(self_val, bitnr_val));
|
1191
1515
|
}
|
1192
1516
|
|
1193
|
-
|
1194
|
-
/**********************************************************************
|
1195
|
-
* Integer Random Numbers *
|
1196
|
-
**********************************************************************/
|
1197
|
-
|
1198
|
-
/**********************************************************************
|
1199
|
-
* Miscellaneous Integer Functions *
|
1200
|
-
**********************************************************************/
|
1201
|
-
|
1202
|
-
/**********************************************************************
|
1203
|
-
* Integer Special Functions *
|
1204
|
-
**********************************************************************/
|
1205
|
-
|
1206
|
-
|
1207
|
-
/**********************************************************************
|
1208
|
-
* _unsorted_ *
|
1209
|
-
**********************************************************************/
|
1210
|
-
|
1211
|
-
/*
|
1212
|
-
* Document-method: com
|
1213
|
-
*
|
1214
|
-
* call-seq:
|
1215
|
-
* integer.com
|
1216
|
-
*
|
1217
|
-
* From the GMP Manual:
|
1218
|
-
*
|
1219
|
-
* Returns the one's complement of +integer+.
|
1220
|
-
*/
|
1221
|
-
/*
|
1222
|
-
* Document-method: com!
|
1223
|
-
*
|
1224
|
-
* call-seq:
|
1225
|
-
* integer.com!
|
1226
|
-
*
|
1227
|
-
* From the GMP Manual:
|
1228
|
-
*
|
1229
|
-
* Sets +integer+ to its one's complement.
|
1230
|
-
*/
|
1231
|
-
DEFUN_INT2INT(com, mpz_com)
|
1232
|
-
/*
|
1233
|
-
* Document-method: nextprime
|
1234
|
-
*
|
1235
|
-
* call-seq:
|
1236
|
-
* integer.nextprime
|
1237
|
-
*
|
1238
|
-
* From the GMP Manual:
|
1239
|
-
*
|
1240
|
-
* Returns the next prime greater than +integer+.
|
1241
|
-
*
|
1242
|
-
* This function uses a probabilistic algorithm to identify primes. For
|
1243
|
-
* practical purposes it's adequate, the chance of a composite passing will be
|
1244
|
-
* extremely small.
|
1245
|
-
*/
|
1246
|
-
/*
|
1247
|
-
* Document-method: nextprime!
|
1248
|
-
*
|
1249
|
-
* call-seq:
|
1250
|
-
* integer.nextprime!
|
1251
|
-
*
|
1252
|
-
* From the GMP Manual:
|
1253
|
-
*
|
1254
|
-
* Sets +integer+ to the next prime greater than +integer+.
|
1255
|
-
*
|
1256
|
-
* This function uses a probabilistic algorithm to identify primes. For
|
1257
|
-
* practical purposes it's adequate, the chance of a composite passing will be
|
1258
|
-
* extremely small.
|
1259
|
-
*/
|
1260
|
-
DEFUN_INT2INT(nextprime, mpz_nextprime)
|
1261
|
-
|
1262
|
-
/*
|
1263
|
-
* call-seq: probab_prime?([reps])
|
1264
|
-
*
|
1265
|
-
* Determine whether +n+ is prime. Returns 2 if +n+ is definitely prime,
|
1266
|
-
* returns 1 if +n+ is probably prime (without being certain), or return 0 if
|
1267
|
-
* +n+ is definitely composite.
|
1268
|
-
*
|
1269
|
-
* This function does some trial divisions, then some Miller-Rabin
|
1270
|
-
* probabilistic primality tests. +reps+ controls how many such tests are done,
|
1271
|
-
* 5 to 10 is a reasonable number, more will reduce the chances of a composite
|
1272
|
-
* being returned as �probably prime�.
|
1273
|
-
*
|
1274
|
-
* Miller-Rabin and similar tests can be more properly called compositeness
|
1275
|
-
* tests. Numbers which fail are known to be composite but those which pass
|
1276
|
-
* might be prime or might be composite. Only a few composites pass, hence
|
1277
|
-
* those which pass are considered probably prime.
|
1278
|
-
*/
|
1279
|
-
VALUE r_gmpz_is_probab_prime(int argc, VALUE* argv, VALUE self)
|
1280
|
-
{
|
1281
|
-
MP_INT *self_val;
|
1282
|
-
int reps_val;
|
1283
|
-
VALUE reps;
|
1284
|
-
mpz_get_struct(self, self_val);
|
1285
|
-
rb_scan_args(argc, argv, "01", &reps);
|
1286
|
-
if(NIL_P(reps)){
|
1287
|
-
reps = INT2FIX(5);
|
1288
|
-
}
|
1289
|
-
if (FIXNUM_P(reps)) {
|
1290
|
-
reps_val = FIX2INT (reps);
|
1291
|
-
} else {
|
1292
|
-
typeerror_as(X, "reps");
|
1293
|
-
}
|
1294
|
-
return INT2FIX(mpz_probab_prime_p(self_val, reps_val));
|
1295
|
-
}
|
1296
|
-
|
1297
1517
|
/*
|
1298
1518
|
* Document-method: popcount
|
1299
1519
|
*
|
@@ -1314,60 +1534,6 @@ VALUE r_gmpz_popcount(VALUE self)
|
|
1314
1534
|
return INT2FIX(mpz_popcount(self_val));
|
1315
1535
|
}
|
1316
1536
|
|
1317
|
-
/*
|
1318
|
-
* Document-method: jacobi
|
1319
|
-
*
|
1320
|
-
* call-seq:
|
1321
|
-
* a.jacobi
|
1322
|
-
*
|
1323
|
-
* <b>90% sure this is incorrectly implemented. Todo.</b>
|
1324
|
-
*
|
1325
|
-
* From the GMP Manual:
|
1326
|
-
*
|
1327
|
-
* Calculate the Jacobi symbol <tt>(a/b)</tt>. This is defined only for +b+
|
1328
|
-
* odd.
|
1329
|
-
*/
|
1330
|
-
VALUE r_gmpz_jacobi(VALUE self)
|
1331
|
-
{
|
1332
|
-
MP_INT *self_val, *res_val;
|
1333
|
-
VALUE res;
|
1334
|
-
mpz_get_struct(self, self_val);
|
1335
|
-
if (mpz_sgn(self_val) != 1)
|
1336
|
-
rb_raise(rb_eRangeError, "you can take jacobi symbol only of positive value");
|
1337
|
-
if (mpz_even_p(self_val))
|
1338
|
-
rb_raise(rb_eRangeError, "you can't take jacobi symbol of even value");
|
1339
|
-
mpz_make_struct_init(res, res_val);
|
1340
|
-
mpz_jacobi(res_val, self_val);
|
1341
|
-
return res;
|
1342
|
-
}
|
1343
|
-
|
1344
|
-
/*
|
1345
|
-
* Document-method: legendre
|
1346
|
-
*
|
1347
|
-
* call-seq:
|
1348
|
-
* a.legendre
|
1349
|
-
*
|
1350
|
-
* <b>90% sure this is incorrectly implemented. Todo.</b>
|
1351
|
-
*
|
1352
|
-
* From the GMP Manual:
|
1353
|
-
*
|
1354
|
-
* Calculate the Legendre symbol <tt>(a/p)</tt>. This is defined only for +p+
|
1355
|
-
* an odd positive prime, and for such +p+ it's identical to the Jacobi symbol.
|
1356
|
-
*/
|
1357
|
-
VALUE r_gmpz_legendre(VALUE self)
|
1358
|
-
{
|
1359
|
-
MP_INT *self_val, *res_val;
|
1360
|
-
VALUE res;
|
1361
|
-
mpz_get_struct(self, self_val);
|
1362
|
-
if (mpz_sgn(self_val) != 1)
|
1363
|
-
rb_raise(rb_eRangeError, "you can take legendre symbol only of positive value");
|
1364
|
-
if (mpz_even_p(self_val))
|
1365
|
-
rb_raise(rb_eRangeError, "you can't take legendre symbol of even value");
|
1366
|
-
mpz_make_struct_init(res, res_val);
|
1367
|
-
mpz_legendre(res_val, self_val);
|
1368
|
-
return res;
|
1369
|
-
}
|
1370
|
-
|
1371
1537
|
/*
|
1372
1538
|
* call-seq:
|
1373
1539
|
* integer[index] = x → nil
|
@@ -1413,57 +1579,68 @@ VALUE r_gmpz_getbit(VALUE self, VALUE bitnr)
|
|
1413
1579
|
return mpz_tstbit(self_val, bitnr_val)?Qtrue:Qfalse;
|
1414
1580
|
}
|
1415
1581
|
|
1582
|
+
|
1583
|
+
/**********************************************************************
|
1584
|
+
* Integer Random Numbers *
|
1585
|
+
**********************************************************************/
|
1586
|
+
|
1587
|
+
/**********************************************************************
|
1588
|
+
* Miscellaneous Integer Functions *
|
1589
|
+
**********************************************************************/
|
1590
|
+
|
1591
|
+
/**********************************************************************
|
1592
|
+
* Integer Special Functions *
|
1593
|
+
**********************************************************************/
|
1594
|
+
|
1595
|
+
|
1596
|
+
/**********************************************************************
|
1597
|
+
* _unsorted_ *
|
1598
|
+
**********************************************************************/
|
1599
|
+
|
1416
1600
|
/*
|
1417
|
-
* Document-method:
|
1601
|
+
* Document-method: com
|
1418
1602
|
*
|
1419
1603
|
* call-seq:
|
1420
|
-
* integer.
|
1604
|
+
* integer.com
|
1421
1605
|
*
|
1422
1606
|
* From the GMP Manual:
|
1423
1607
|
*
|
1424
|
-
*
|
1608
|
+
* Returns the one's complement of +integer+.
|
1425
1609
|
*/
|
1426
|
-
DEFUN_INT_COND_P(is_even,mpz_even_p)
|
1427
1610
|
/*
|
1428
|
-
* Document-method:
|
1611
|
+
* Document-method: com!
|
1429
1612
|
*
|
1430
1613
|
* call-seq:
|
1431
|
-
* integer.
|
1614
|
+
* integer.com!
|
1432
1615
|
*
|
1433
1616
|
* From the GMP Manual:
|
1434
1617
|
*
|
1435
|
-
*
|
1618
|
+
* Sets +integer+ to its one's complement.
|
1436
1619
|
*/
|
1437
|
-
|
1620
|
+
DEFUN_INT2INT(com, mpz_com)
|
1621
|
+
|
1438
1622
|
/*
|
1439
|
-
* Document-method:
|
1623
|
+
* Document-method: even?
|
1440
1624
|
*
|
1441
1625
|
* call-seq:
|
1442
|
-
* integer.
|
1626
|
+
* integer.even?
|
1443
1627
|
*
|
1444
1628
|
* From the GMP Manual:
|
1445
1629
|
*
|
1446
|
-
*
|
1447
|
-
* integer is an integer. Under this definition both 0 and 1 are considered to
|
1448
|
-
* be perfect squares.
|
1630
|
+
* Determines whether integer is even. Returns true or false.
|
1449
1631
|
*/
|
1450
|
-
DEFUN_INT_COND_P(
|
1632
|
+
DEFUN_INT_COND_P(is_even,mpz_even_p)
|
1451
1633
|
/*
|
1452
|
-
* Document-method:
|
1634
|
+
* Document-method: odd?
|
1453
1635
|
*
|
1454
1636
|
* call-seq:
|
1455
|
-
* integer.
|
1637
|
+
* integer.odd?
|
1456
1638
|
*
|
1457
1639
|
* From the GMP Manual:
|
1458
1640
|
*
|
1459
|
-
*
|
1460
|
-
* and b, with b>1, such that integer equals a raised to the power b.
|
1461
|
-
*
|
1462
|
-
* Under this definition both 0 and 1 are considered to be perfect powers.
|
1463
|
-
* Negative values of integers are accepted, but of course can only be odd
|
1464
|
-
* perfect powers.
|
1641
|
+
* Determines whether integer is odd. Returns true or false.
|
1465
1642
|
*/
|
1466
|
-
DEFUN_INT_COND_P(
|
1643
|
+
DEFUN_INT_COND_P(is_odd,mpz_odd_p)
|
1467
1644
|
|
1468
1645
|
/*
|
1469
1646
|
* call-seq:
|
@@ -1480,100 +1657,6 @@ VALUE r_gmpz_sgn(VALUE self)
|
|
1480
1657
|
return INT2FIX(mpz_sgn(self_val));
|
1481
1658
|
}
|
1482
1659
|
|
1483
|
-
/*
|
1484
|
-
* call-seq:
|
1485
|
-
* integer.powmod(exp, mod)
|
1486
|
-
*
|
1487
|
-
* From the GMP Manual:
|
1488
|
-
*
|
1489
|
-
* Returns +integer+ raised to +exp+ modulo +mod+.
|
1490
|
-
*
|
1491
|
-
* Negative +exp+ is supported if an inverse <tt>integer^-1</tt> mod
|
1492
|
-
* <tt>mod</tt> exists. If an inverse doesn't exist then a divide by zero is
|
1493
|
-
* raised.
|
1494
|
-
*/
|
1495
|
-
VALUE r_gmpz_powm(VALUE self, VALUE exp, VALUE mod)
|
1496
|
-
{
|
1497
|
-
MP_INT *self_val, *res_val, *mod_val, *exp_val;
|
1498
|
-
VALUE res;
|
1499
|
-
int free_mod_val = 0;
|
1500
|
-
|
1501
|
-
if (GMPZ_P(mod)) {
|
1502
|
-
mpz_get_struct(mod, mod_val);
|
1503
|
-
if (mpz_sgn(mod_val) <= 0) {
|
1504
|
-
rb_raise (rb_eRangeError, "modulus must be positive");
|
1505
|
-
}
|
1506
|
-
} else if (FIXNUM_P(mod)) {
|
1507
|
-
if (FIX2INT(mod) <= 0) {
|
1508
|
-
rb_raise (rb_eRangeError, "modulus must be positive");
|
1509
|
-
}
|
1510
|
-
mpz_temp_alloc (mod_val);
|
1511
|
-
mpz_init_set_ui(mod_val, FIX2INT(mod));
|
1512
|
-
free_mod_val = 1;
|
1513
|
-
} else if (BIGNUM_P(mod)) {
|
1514
|
-
mpz_temp_from_bignum (mod_val, mod);
|
1515
|
-
if (mpz_sgn(mod_val) <= 0) {
|
1516
|
-
mpz_temp_free(mod_val);
|
1517
|
-
rb_raise (rb_eRangeError, "modulus must be positive");
|
1518
|
-
}
|
1519
|
-
free_mod_val = 1;
|
1520
|
-
} else {
|
1521
|
-
typeerror_as (ZXB, "modulus");
|
1522
|
-
}
|
1523
|
-
mpz_make_struct_init(res, res_val);
|
1524
|
-
mpz_get_struct(self, self_val);
|
1525
|
-
|
1526
|
-
if (GMPZ_P(exp)) {
|
1527
|
-
mpz_get_struct(exp, exp_val);
|
1528
|
-
if (mpz_sgn(mod_val) < 0) {
|
1529
|
-
rb_raise (rb_eRangeError, "exponent must be nonnegative");
|
1530
|
-
}
|
1531
|
-
mpz_powm (res_val, self_val, exp_val, mod_val);
|
1532
|
-
} else if (FIXNUM_P(exp)) {
|
1533
|
-
if (FIX2INT(exp) < 0)
|
1534
|
-
{
|
1535
|
-
if (free_mod_val)
|
1536
|
-
mpz_temp_free(mod_val);
|
1537
|
-
rb_raise (rb_eRangeError, "exponent must be nonnegative");
|
1538
|
-
}
|
1539
|
-
mpz_powm_ui (res_val, self_val, FIX2INT(exp), mod_val);
|
1540
|
-
} else if (BIGNUM_P(exp)) {
|
1541
|
-
mpz_temp_from_bignum (exp_val, exp);
|
1542
|
-
mpz_powm (res_val, self_val, exp_val, mod_val);
|
1543
|
-
mpz_temp_free (exp_val);
|
1544
|
-
} else {
|
1545
|
-
if (free_mod_val)
|
1546
|
-
mpz_temp_free(mod_val);
|
1547
|
-
typeerror_as (ZXB, "exponent");
|
1548
|
-
}
|
1549
|
-
if (free_mod_val)
|
1550
|
-
mpz_temp_free(mod_val);
|
1551
|
-
return res;
|
1552
|
-
}
|
1553
|
-
|
1554
|
-
/*
|
1555
|
-
* Document-method: **
|
1556
|
-
*
|
1557
|
-
* call-seq:
|
1558
|
-
* integer ** exp
|
1559
|
-
*
|
1560
|
-
* From the GMP Manual:
|
1561
|
-
*
|
1562
|
-
* Returns +integer+ raised to +exp+. The case 0^0 yields 1.
|
1563
|
-
*/
|
1564
|
-
DEFUN_INT_F_UL(pow,mpz_pow_ui,"exponent")
|
1565
|
-
/*
|
1566
|
-
* Document-method: <<
|
1567
|
-
*
|
1568
|
-
* call-seq:
|
1569
|
-
* integer << n
|
1570
|
-
*
|
1571
|
-
* From the GMP Manual:
|
1572
|
-
*
|
1573
|
-
* Returns +integer+ times 2 raised to +n+. This operation can also be defined
|
1574
|
-
* as a left shift by +n+ bits.
|
1575
|
-
*/
|
1576
|
-
DEFUN_INT_F_UL(shl,mpz_mul_2exp,"shift size")
|
1577
1660
|
DEFUN_INT_F_UL(fshr,mpz_fdiv_q_2exp,"shift size")
|
1578
1661
|
DEFUN_INT_F_UL(tshr,mpz_tdiv_q_2exp,"shift size")
|
1579
1662
|
DEFUN_INT_F_UL(fshrm,mpz_fdiv_r_2exp,"mark size")
|
@@ -1697,16 +1780,20 @@ void init_gmpz()
|
|
1697
1780
|
rb_define_method(cGMP_Z, "to_s", r_gmpz_to_s, -1);
|
1698
1781
|
|
1699
1782
|
// Integer Arithmetic
|
1700
|
-
rb_define_method(cGMP_Z, "+",
|
1783
|
+
rb_define_method(cGMP_Z, "+", r_gmpz_add, 1);
|
1701
1784
|
rb_define_method(cGMP_Z, "add!", r_gmpz_add_self, 1);
|
1702
|
-
rb_define_method(cGMP_Z, "-",
|
1785
|
+
rb_define_method(cGMP_Z, "-", r_gmpz_sub, 1);
|
1703
1786
|
rb_define_method(cGMP_Z, "sub!", r_gmpz_sub_self, 1);
|
1704
|
-
rb_define_method(cGMP_Z, "*",
|
1705
|
-
rb_define_method(cGMP_Z, "
|
1787
|
+
rb_define_method(cGMP_Z, "*", r_gmpz_mul, 1);
|
1788
|
+
rb_define_method(cGMP_Z, "<<", r_gmpz_shl, 1);
|
1789
|
+
rb_define_method(cGMP_Z, "neg", r_gmpz_neg, 0);
|
1706
1790
|
rb_define_method(cGMP_Z, "neg!", r_gmpz_neg_self, 0);
|
1791
|
+
rb_define_method(cGMP_Z, "-@", r_gmpz_neg, 0);
|
1792
|
+
rb_define_method(cGMP_Z, "abs", r_gmpz_abs, 0);
|
1793
|
+
rb_define_method(cGMP_Z, "abs!", r_gmpz_abs_self, 0);
|
1707
1794
|
|
1708
1795
|
// Integer Division
|
1709
|
-
rb_define_method(cGMP_Z, "/",
|
1796
|
+
rb_define_method(cGMP_Z, "/", r_gmpz_div, 1);
|
1710
1797
|
rb_define_method(cGMP_Z, "tdiv", r_gmpz_tdiv, 1);
|
1711
1798
|
rb_define_method(cGMP_Z, "tmod", r_gmpz_tmod, 1);
|
1712
1799
|
rb_define_method(cGMP_Z, "fdiv", r_gmpz_fdiv, 1);
|
@@ -1715,15 +1802,30 @@ void init_gmpz()
|
|
1715
1802
|
rb_define_method(cGMP_Z, "cmod", r_gmpz_cmod, 1);
|
1716
1803
|
|
1717
1804
|
// Integer Exponentiation
|
1718
|
-
rb_define_singleton_method(cGMP_Z, "pow",
|
1805
|
+
rb_define_singleton_method(cGMP_Z, "pow", r_gmpzsg_pow, 2);
|
1806
|
+
rb_define_method(cGMP_Z, "**", r_gmpz_pow, 1);
|
1807
|
+
rb_define_method(cGMP_Z, "powmod", r_gmpz_powm, 2);
|
1719
1808
|
|
1720
1809
|
// Integer Roots
|
1721
|
-
rb_define_method(cGMP_Z, "root",
|
1810
|
+
rb_define_method(cGMP_Z, "root", r_gmpz_root, 1);
|
1811
|
+
rb_define_method(cGMP_Z, "sqrt", r_gmpz_sqrt, 0);
|
1812
|
+
rb_define_method(cGMP_Z, "sqrt!", r_gmpz_sqrt_self, 0);
|
1813
|
+
rb_define_method(cGMP_Z, "sqrtrem", r_gmpz_sqrtrem, 0);
|
1814
|
+
rb_define_method(cGMP_Z, "square?", r_gmpz_is_square, 0);
|
1815
|
+
rb_define_method(cGMP_Z, "power?", r_gmpz_is_power, 0);
|
1722
1816
|
|
1723
1817
|
// Number Theoretic Functions
|
1724
|
-
rb_define_method(cGMP_Z, "
|
1725
|
-
|
1726
|
-
|
1818
|
+
rb_define_method( cGMP_Z, "probab_prime?", r_gmpz_is_probab_prime, -1);
|
1819
|
+
rb_define_method( cGMP_Z, "nextprime", r_gmpz_nextprime, 0);
|
1820
|
+
rb_define_method( cGMP_Z, "nextprime!", r_gmpz_nextprime_self, 0);
|
1821
|
+
rb_define_alias( cGMP_Z, "next_prime", "nextprime");
|
1822
|
+
rb_define_alias( cGMP_Z, "next_prime!", "nextprime!");
|
1823
|
+
rb_define_method( cGMP_Z, "jacobi", r_gmpz_jacobi, 1);
|
1824
|
+
rb_define_singleton_method(cGMP_Z, "jacobi", r_gmpzsg_jacobi, 2);
|
1825
|
+
rb_define_method( cGMP_Z, "legendre", r_gmpz_legendre, 1);
|
1826
|
+
rb_define_method( cGMP_Z, "remove", r_gmpz_remove, 1);
|
1827
|
+
rb_define_singleton_method(cGMP_Z, "fac", r_gmpzsg_fac, 1);
|
1828
|
+
rb_define_singleton_method(cGMP_Z, "fib", r_gmpzsg_fib, 1);
|
1727
1829
|
|
1728
1830
|
// Integer Comparisons
|
1729
1831
|
rb_define_method(cGMP_Z, "<=>", r_gmpz_cmp, 1);
|
@@ -1734,9 +1836,6 @@ void init_gmpz()
|
|
1734
1836
|
rb_define_method(cGMP_Z, "cmpabs", r_gmpz_cmpabs, 1);
|
1735
1837
|
|
1736
1838
|
// _unsorted_
|
1737
|
-
rb_define_method(cGMP_Z, "-@", r_gmpz_neg, 0);
|
1738
|
-
rb_define_method(cGMP_Z, "abs", r_gmpz_abs, 0);
|
1739
|
-
rb_define_method(cGMP_Z, "abs!", r_gmpz_abs_self, 0);
|
1740
1839
|
rb_define_method(cGMP_Z, "com", r_gmpz_com, 0);
|
1741
1840
|
rb_define_method(cGMP_Z, "com!", r_gmpz_com_self, 0);
|
1742
1841
|
rb_define_method(cGMP_Z, "&", r_gmpz_and, 1);
|
@@ -1750,25 +1849,11 @@ void init_gmpz()
|
|
1750
1849
|
rb_define_method(cGMP_Z, "odd?", r_gmpz_is_odd, 0);
|
1751
1850
|
rb_define_method(cGMP_Z, "sgn", r_gmpz_sgn, 0);
|
1752
1851
|
|
1753
|
-
rb_define_method(cGMP_Z, "**", r_gmpz_pow, 1);
|
1754
|
-
rb_define_method(cGMP_Z, "powmod", r_gmpz_powm, 2);
|
1755
|
-
|
1756
1852
|
rb_define_method(cGMP_Z, "==", r_gmpz_eq, 1);
|
1757
1853
|
rb_define_method(cGMP_Z, ">>", r_gmpz_fshr, 1);
|
1758
|
-
rb_define_method(cGMP_Z, "<<", r_gmpz_shl, 1);
|
1759
1854
|
rb_define_method(cGMP_Z, "tshr", r_gmpz_tshr, 1);
|
1760
1855
|
rb_define_method(cGMP_Z, "lastbits_sgn", r_gmpz_tshrm, 1);
|
1761
1856
|
rb_define_method(cGMP_Z, "lastbits_pos", r_gmpz_fshrm, 1);
|
1762
|
-
rb_define_method(cGMP_Z, "square?", r_gmpz_is_square, 0);
|
1763
|
-
rb_define_method(cGMP_Z, "power?", r_gmpz_is_power, 0);
|
1764
|
-
rb_define_method(cGMP_Z, "sqrt", r_gmpz_sqrt, 0);
|
1765
|
-
rb_define_method(cGMP_Z, "sqrt!", r_gmpz_sqrt_self, 0);
|
1766
|
-
rb_define_method(cGMP_Z, "sqrtrem", r_gmpz_sqrtrem, 0);
|
1767
|
-
rb_define_method(cGMP_Z, "jacobi", r_gmpz_jacobi, 0);
|
1768
|
-
rb_define_method(cGMP_Z, "legendre", r_gmpz_legendre, 0);
|
1769
|
-
rb_define_method(cGMP_Z, "probab_prime?", r_gmpz_is_probab_prime, -1);
|
1770
|
-
rb_define_method(cGMP_Z, "nextprime", r_gmpz_nextprime, 0);
|
1771
|
-
rb_define_method(cGMP_Z, "nextprime!", r_gmpz_nextprime_self, 0);
|
1772
1857
|
rb_define_method(cGMP_Z, "popcount", r_gmpz_popcount, 0);
|
1773
1858
|
|
1774
1859
|
}
|