gmp 0.2.1 → 0.2.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
}
|