gmp 0.5.3-x86-mingw32 → 0.5.23-x86-mingw32

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/ext/gmp.c CHANGED
@@ -98,55 +98,6 @@ static VALUE r_gmpfsg_set_default_prec(VALUE klass, VALUE arg)
98
98
  }
99
99
 
100
100
  #ifdef MPFR
101
- static VALUE r_gmpfsg_get_default_rounding_mode(VALUE klass)
102
- {
103
- (void)klass;
104
- const char *rounding_string_val;
105
- rounding_string_val = mpfr_print_rnd_mode (mpfr_get_default_rounding_mode ());
106
- if ( rounding_string_val == NULL ) {
107
- return Qnil;
108
- }
109
- else {
110
- return rb_const_get (mGMP, rb_intern (rounding_string_val));
111
- }
112
- }
113
-
114
- static VALUE r_gmpfsg_set_default_rounding_mode(VALUE klass, VALUE arg)
115
- {
116
- (void)klass;
117
- VALUE mode;
118
- if (GMPRND_P(arg)) {
119
- mode = rb_funcall (arg, rb_intern("mode"), 0);
120
- if (FIX2INT(mode) < 0 || FIX2INT(mode) > 3) {
121
- rb_raise(rb_eRangeError, "rounding mode must be one of the rounding mode constants.");
122
- }
123
- } else {
124
- rb_raise(rb_eTypeError, "rounding mode must be one of the rounding mode constants.");
125
- }
126
-
127
- switch (FIX2INT(mode)) {
128
- case 0:
129
- mpfr_set_default_rounding_mode (GMP_RNDN);
130
- break;
131
- case 1:
132
- mpfr_set_default_rounding_mode (GMP_RNDZ);
133
- break;
134
- case 2:
135
- mpfr_set_default_rounding_mode (GMP_RNDU);
136
- break;
137
- case 3:
138
- mpfr_set_default_rounding_mode (GMP_RNDD);
139
- break;
140
- #if MPFR_VERSION_MAJOR>2
141
- case 4:
142
- mpfr_set_default_rounding_mode (MPFR_RNDA);
143
- break;
144
- #endif
145
- }
146
-
147
- return Qnil;
148
- }
149
-
150
101
  mp_rnd_t r_get_rounding_mode(VALUE rnd)
151
102
  {
152
103
  VALUE mode;
@@ -193,12 +144,13 @@ mp_rnd_t r_get_rounding_mode(VALUE rnd)
193
144
 
194
145
  void Init_gmp() {
195
146
  mGMP = rb_define_module("GMP");
196
- rb_define_const(mGMP, "GMP_VERSION", rb_str_new2(gmp_version));
197
- rb_define_const(mGMP, "GMP_CC", rb_str_new2(__GMP_CC));
198
- rb_define_const(mGMP, "GMP_CFLAGS", rb_str_new2(__GMP_CFLAGS));
147
+ rb_define_const(mGMP, "GMP_VERSION", rb_str_new2(gmp_version));
148
+ rb_define_const(mGMP, "GMP_CC", rb_str_new2(__GMP_CC));
149
+ rb_define_const(mGMP, "GMP_CFLAGS", rb_str_new2(__GMP_CFLAGS));
199
150
  rb_define_const(mGMP, "GMP_BITS_PER_LIMB", INT2FIX(mp_bits_per_limb));
151
+ rb_define_const(mGMP, "GMP_NUMB_MAX", ULONG2NUM(GMP_NUMB_MAX));
200
152
  #ifdef MPFR
201
- rb_define_const(mGMP, "MPFR_VERSION", rb_str_new2(MPFR_VERSION_STRING));
153
+ rb_define_const(mGMP, "MPFR_VERSION", rb_str_new2(MPFR_VERSION_STRING));
202
154
  rb_define_const(mGMP, "MPFR_PREC_MIN", INT2FIX(MPFR_PREC_MIN));
203
155
  rb_define_const(mGMP, "MPFR_PREC_MAX", INT2FIX(MPFR_PREC_MAX));
204
156
  #endif /* MPFR */
@@ -220,8 +172,6 @@ void Init_gmp() {
220
172
  rb_define_singleton_method (cGMP_F, "default_prec=", r_gmpfsg_set_default_prec, 1);
221
173
  #ifdef MPFR
222
174
  cGMP_Rnd = rb_define_class_under (mGMP, "Rnd", rb_cObject);
223
- rb_define_singleton_method (cGMP_F, "default_rounding_mode", r_gmpfsg_get_default_rounding_mode, 0);
224
- rb_define_singleton_method (cGMP_F, "default_rounding_mode=", r_gmpfsg_set_default_rounding_mode, 1);
225
175
  init_gmprnd ();
226
176
  #endif /* MPFR */
227
177
  rb_define_method (cGMP_F, "coerce", r_gmpf_coerce, 1); // new method - testing
data/ext/gmp.so CHANGED
Binary file
data/ext/gmpf.c CHANGED
@@ -10,17 +10,6 @@
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
24
13
  */
25
14
 
26
15
  /**********************************************************************
@@ -250,6 +239,12 @@ VALUE r_gmpmod_f(int argc, VALUE *argv, VALUE module)
250
239
  * Converting Floats *
251
240
  **********************************************************************/
252
241
 
242
+ /*
243
+ * call-seq:
244
+ * x.to_d
245
+ *
246
+ * Returns _x_ as a Float.
247
+ */
253
248
  VALUE r_gmpf_to_d(VALUE self)
254
249
  {
255
250
  MP_FLOAT *self_val;
@@ -260,12 +255,10 @@ VALUE r_gmpf_to_d(VALUE self)
260
255
 
261
256
  #ifdef MPFR
262
257
  /*
263
- * Document-method: to_s
264
- *
265
258
  * call-seq:
266
- * float.to_s
259
+ * x.to_s
267
260
  *
268
- * Returns the decimal representation of +float+, as a string.
261
+ * Returns the decimal representation of _x_, as a String.
269
262
  */
270
263
  VALUE r_gmpf_to_s(VALUE self)
271
264
  {
@@ -301,12 +294,10 @@ VALUE r_gmpf_to_s(VALUE self)
301
294
  }
302
295
  #else
303
296
  /*
304
- * Document-method: to_s
305
- *
306
297
  * call-seq:
307
- * float.to_s
298
+ * x.to_s
308
299
  *
309
- * Returns the decimal representation of +float+, as a string.
300
+ * Returns the decimal representation of _x_, as a string.
310
301
  */
311
302
  VALUE r_gmpf_to_s(VALUE self)
312
303
  {
@@ -346,9 +337,9 @@ VALUE r_gmpf_to_s(VALUE self)
346
337
  #ifndef MPFR
347
338
  /*
348
339
  * call-seq:
349
- * float + other
340
+ * x + y
350
341
  *
351
- * Returns the sum of +float+ and +other+. +other+ can be
342
+ * Returns the sum of _x_ and _y_. _y_ must be an instance of:
352
343
  * * GMP::Z
353
344
  * * Fixnum
354
345
  * * GMP::Q
@@ -404,9 +395,9 @@ VALUE r_gmpf_add(VALUE self, VALUE arg)
404
395
  #else
405
396
  /*
406
397
  * call-seq:
407
- * float + other
398
+ * x + y
408
399
  *
409
- * Returns the sum of +float+ and +other+. +other+ can be
400
+ * Returns the sum of _x_ and _y_. _y_ must be an instance of:
410
401
  * * GMP::Z
411
402
  * * Fixnum
412
403
  * * GMP::Q
@@ -470,9 +461,9 @@ DEFUN_F_ZQXFBD2F(mul)
470
461
 
471
462
  /*
472
463
  * call-seq:
473
- * float1 - float2
464
+ * x - y
474
465
  *
475
- * Subtracts +float2+ from +float1+. +float2+ can be
466
+ * Subtracts _y_ from _x_. _y_ must be an instance of:
476
467
  * * GMP::Z
477
468
  * * Fixnum
478
469
  * * GMP::Q
@@ -528,9 +519,9 @@ VALUE r_gmpf_sub(VALUE self, VALUE arg)
528
519
 
529
520
  /*
530
521
  * call-seq:
531
- * float * other
522
+ * x * y
532
523
  *
533
- * Returns the product of +float+ and +other+. +other+ can be
524
+ * Returns the product of _x_ and _y_. _y_ can be
534
525
  * * GMP::Z
535
526
  * * Fixnum
536
527
  * * GMP::Q
@@ -544,7 +535,6 @@ VALUE r_gmpf_mul(VALUE self, VALUE arg)
544
535
  MP_RAT *arg_val_q;
545
536
  MP_INT *arg_val_z;
546
537
  VALUE res;
547
- //unsigned long prec;
548
538
  mpfr_prec_t prec;
549
539
 
550
540
  mpf_get_struct_prec (self, self_val, prec);
@@ -587,10 +577,10 @@ VALUE r_gmpf_mul(VALUE self, VALUE arg)
587
577
 
588
578
  /*
589
579
  * call-seq:
590
- * float ** integer
580
+ * x ** y
591
581
  *
592
- * Returns +float+ raised to the +integer+ power. +integer+ must be
593
- * * Fixnum or Bignum
582
+ * Returns _x_ raised to the _y_ power. _y_ must be
583
+ * * an instance of Fixnum or Bignum
594
584
  * * non-negative
595
585
  */
596
586
  VALUE r_gmpf_pow(VALUE self, VALUE arg)
@@ -617,65 +607,11 @@ VALUE r_gmpf_pow(VALUE self, VALUE arg)
617
607
  return res;
618
608
  }
619
609
 
620
- #ifdef MPFR
621
- /*
622
- * call-seq:
623
- * float ** other
624
- *
625
- * Returns +float+ raised to the +other+ power. +other+ must be an instance of
626
- * * Fixnum
627
- * * Bignum
628
- * * Float
629
- * * GMP::Z
630
- * * GMP::F
631
- */
632
- /*VALUE r_gmpfr_pow(int argc, VALUE *argv, VALUE self)
633
- {
634
- MP_FLOAT *self_val, *res_val, *arg_val_f;
635
- VALUE arg, rnd_mode, res_prec;
636
- unsigned long arg_val, prec, res_prec_value;
637
- mp_rnd_t rnd_mode_value;
638
- MP_INT *arg_val_z;
639
- VALUE res;
640
-
641
- rb_scan_args (argc, argv, "12", &arg, &rnd_mode, &res_prec);
642
-
643
- mpf_get_struct_prec (self, self_val, prec);
644
-
645
- if (NIL_P (rnd_mode)) { rnd_mode_value = __gmp_default_rounding_mode; }
646
- else { rnd_mode_value = r_get_rounding_mode(rnd_mode); }
647
- if (NIL_P (res_prec)) { res_prec_value = prec; }
648
- else { res_prec_value = FIX2INT (res_prec); }
649
- mpf_make_struct_init (res, res_val, res_prec_value);
650
-
651
- if (FIXNUM_P(arg)) {
652
- mpfr_pow_ui(res_val, self_val, FIX2NUM(arg), rnd_mode_value);
653
- } else if (BIGNUM_P(arg)) {
654
- mpz_temp_from_bignum(arg_val_z, arg);
655
- mpfr_pow_z (res_val, self_val, arg_val_z, rnd_mode_value);
656
- mpz_temp_free(arg_val_z);
657
- } else if (FLOAT_P(arg)) {
658
- r_mpf_set_d (res_val, NUM2DBL(arg));
659
- mpfr_pow (res_val, self_val, res_val, rnd_mode_value);
660
- } else if (GMPZ_P(arg)) {
661
- mpz_get_struct (arg, arg_val_z);
662
- mpfr_pow_z (res_val, self_val, arg_val_z, rnd_mode_value);
663
- } else if (GMPF_P(arg)) {
664
- mpf_get_struct (arg, arg_val_f);
665
- mpfr_pow (res_val, self_val, arg_val_f, rnd_mode_value);
666
- } else {
667
- typeerror(ZFXBD);
668
- }
669
-
670
- return res;
671
- }*/
672
- #endif
673
-
674
610
  /*
675
611
  * call-seq:
676
- * float1 / float2
612
+ * x / y
677
613
  *
678
- * Divides +float1+ by +float2+. +float2+ can be
614
+ * Divides _x_ by _y_. _y_ can be
679
615
  * * GMP::Z
680
616
  * * Fixnum
681
617
  * * GMP::Q
@@ -729,45 +665,93 @@ VALUE r_gmpf_div(VALUE self, VALUE arg)
729
665
  return res;
730
666
  }
731
667
 
668
+ #ifdef MPFR
669
+ /*
670
+ * call-seq:
671
+ * float ** other
672
+ *
673
+ * Returns _x_ raised to the _y_ power. _y_ must be an instance of
674
+ * * Fixnum
675
+ * * Bignum
676
+ * * Float
677
+ * * GMP::Z
678
+ * * GMP::F
679
+ */
680
+ /*VALUE r_gmpfr_pow(int argc, VALUE *argv, VALUE self)
681
+ {
682
+ MP_FLOAT *self_val, *res_val, *arg_val_f;
683
+ VALUE arg, rnd_mode, res_prec;
684
+ unsigned long arg_val, prec, res_prec_value;
685
+ mp_rnd_t rnd_mode_value;
686
+ MP_INT *arg_val_z;
687
+ VALUE res;
688
+
689
+ rb_scan_args (argc, argv, "12", &arg, &rnd_mode, &res_prec);
690
+
691
+ mpf_get_struct_prec (self, self_val, prec);
692
+
693
+ if (NIL_P (rnd_mode)) { rnd_mode_value = __gmp_default_rounding_mode; }
694
+ else { rnd_mode_value = r_get_rounding_mode(rnd_mode); }
695
+ if (NIL_P (res_prec)) { res_prec_value = prec; }
696
+ else { res_prec_value = FIX2INT (res_prec); }
697
+ mpf_make_struct_init (res, res_val, res_prec_value);
698
+
699
+ if (FIXNUM_P(arg)) {
700
+ mpfr_pow_ui(res_val, self_val, FIX2NUM(arg), rnd_mode_value);
701
+ } else if (BIGNUM_P(arg)) {
702
+ mpz_temp_from_bignum(arg_val_z, arg);
703
+ mpfr_pow_z (res_val, self_val, arg_val_z, rnd_mode_value);
704
+ mpz_temp_free(arg_val_z);
705
+ } else if (FLOAT_P(arg)) {
706
+ r_mpf_set_d (res_val, NUM2DBL(arg));
707
+ mpfr_pow (res_val, self_val, res_val, rnd_mode_value);
708
+ } else if (GMPZ_P(arg)) {
709
+ mpz_get_struct (arg, arg_val_z);
710
+ mpfr_pow_z (res_val, self_val, arg_val_z, rnd_mode_value);
711
+ } else if (GMPF_P(arg)) {
712
+ mpf_get_struct (arg, arg_val_f);
713
+ mpfr_pow (res_val, self_val, arg_val_f, rnd_mode_value);
714
+ } else {
715
+ typeerror(ZFXBD);
716
+ }
732
717
 
718
+ return res;
719
+ }*/
720
+ #endif
733
721
 
734
722
  /*
735
723
  * Document-method: neg
736
724
  *
737
725
  * call-seq:
738
- * float.neg
739
- * -float
726
+ * x.neg
727
+ * -x
740
728
  *
741
- * From the GMP Manual:
742
- *
743
- * Returns -+float+.
729
+ * Returns -_x_.
744
730
  */
745
731
  /*
746
732
  * Document-method: neg!
747
733
  *
748
734
  * call-seq:
749
- * float.neg!
735
+ * x.neg!
750
736
  *
751
- * Sets +float+ to -+float+.
737
+ * Sets _x_ to -_x_.
752
738
  */
753
739
  DEFUN_FLOAT2FLOAT(neg,mpf_neg)
754
740
  /*
755
741
  * Document-method: abs
756
742
  *
757
743
  * call-seq:
758
- * float.abs
744
+ * x.abs
759
745
  *
760
- * From the GMP Manual:
761
- *
762
- * Returns the absolute value of +float+.
746
+ * Returns the absolute value of _x_.
763
747
  */
764
748
  /*
765
749
  * Document-method: abs!
766
750
  *
767
751
  * call-seq:
768
- * float.abs!
752
+ * x.abs!
769
753
  *
770
- * Sets +float+ to the absolute value of +float+.
754
+ * Sets _x_ to the absolute value of _x_.
771
755
  */
772
756
  DEFUN_FLOAT2FLOAT(abs,mpf_abs)
773
757
 
@@ -793,7 +777,10 @@ int mpf_cmp_value(MP_FLOAT *self_val, VALUE arg)
793
777
  }
794
778
  }
795
779
 
796
- /* what does really "equal" mean ? it's not obvious */
780
+ /*
781
+ * what does really "equal" mean ? it's not obvious
782
+ * Is this a note that I, SRR, put in here? It is now obvious to me...
783
+ */
797
784
  VALUE r_gmpf_eq(VALUE self, VALUE arg)
798
785
  {
799
786
  MP_FLOAT *self_val;
@@ -820,6 +807,28 @@ DEFUN_FLOAT_CMP(le,<=)
820
807
  DEFUN_FLOAT_CMP(gt,>)
821
808
  DEFUN_FLOAT_CMP(ge,>=)
822
809
 
810
+ /*
811
+ * call-seq:
812
+ * x.sgn
813
+ *
814
+ * Returns +1 if _x_ > 0, 0 if _x_ == 0, and -1 if _x_ < 0.
815
+ */
816
+ VALUE r_gmpf_sgn(VALUE self)
817
+ {
818
+ MP_FLOAT *self_val;
819
+ mpf_get_struct (self, self_val);
820
+ return INT2FIX (mpf_sgn (self_val));
821
+ }
822
+
823
+
824
+ /**********************************************************************
825
+ * Miscellaneous Float Functions *
826
+ **********************************************************************/
827
+
828
+ DEFUN_FLOAT2FLOAT(floor,mpf_floor)
829
+ DEFUN_FLOAT2FLOAT(trunc,mpf_trunc)
830
+ DEFUN_FLOAT2FLOAT(ceil,mpf_ceil)
831
+
823
832
 
824
833
  #ifdef MPFR
825
834
 
@@ -827,15 +836,14 @@ DEFUN_FLOAT_CMP(ge,>=)
827
836
  VALUE r_gmpfr_##name(int argc, VALUE *argv, VALUE self) \
828
837
  { \
829
838
  MP_FLOAT *self_val, *res_val; \
830
- VALUE rnd_mode, res_prec; \
839
+ VALUE rnd_mode, res_prec, res; \
831
840
  mpfr_prec_t prec, res_prec_value; \
832
841
  mp_rnd_t rnd_mode_val; \
833
- VALUE res; \
834
- \
835
- rb_scan_args (argc, argv, "02", &rnd_mode, &res_prec); \
836
842
  \
837
843
  mpf_get_struct_prec (self, self_val, prec); \
838
- if (NIL_P (rnd_mode)) { rnd_mode_val = __gmp_default_rounding_mode; } \
844
+ \
845
+ rb_scan_args (argc, argv, "02", &rnd_mode, &res_prec); \
846
+ if (NIL_P (rnd_mode)) { rnd_mode_val = __gmp_default_rounding_mode; } \
839
847
  else { rnd_mode_val = r_get_rounding_mode(rnd_mode); } \
840
848
  if (NIL_P (res_prec)) { res_prec_value = prec; } \
841
849
  else { res_prec_value = FIX2INT (res_prec); } \
@@ -845,7 +853,31 @@ VALUE r_gmpfr_##name(int argc, VALUE *argv, VALUE self) \
845
853
  return res; \
846
854
  }
847
855
 
848
- #define MPFR_SINGLE_1ARG_FUNCTION(name) \
856
+ #define MPFR_DOUBLE_FUNCTION(name) \
857
+ VALUE r_gmpfr_##name(int argc, VALUE *argv, VALUE self) \
858
+ { \
859
+ MP_FLOAT *self_val, *sin_val, *cos_val; \
860
+ VALUE rnd_mode, sin_prec, cos_prec, sinn, coss; \
861
+ mpfr_prec_t prec, sin_prec_val, cos_prec_val; \
862
+ mp_rnd_t rnd_mode_val; \
863
+ \
864
+ mpf_get_struct_prec (self, self_val, prec); \
865
+ \
866
+ rb_scan_args (argc, argv, "03", &rnd_mode, &sin_prec, &cos_prec); \
867
+ if (NIL_P (rnd_mode)) { rnd_mode_val = __gmp_default_rounding_mode; } \
868
+ else { rnd_mode_val = r_get_rounding_mode(rnd_mode); } \
869
+ if (NIL_P (sin_prec)) { sin_prec_val = prec; } \
870
+ else { sin_prec_val = FIX2INT (sin_prec); } \
871
+ if (NIL_P (cos_prec)) { cos_prec_val = sin_prec_val; } \
872
+ else { cos_prec_val = FIX2INT (cos_prec); } \
873
+ mpf_make_struct_init (sinn, sin_val, sin_prec_val); \
874
+ mpf_make_struct_init (coss, cos_val, cos_prec_val); \
875
+ mpfr_##name (sin_val, cos_val, self_val, rnd_mode_val); \
876
+ \
877
+ return rb_ary_new3(2, sinn, coss); \
878
+ }
879
+
880
+ #define MPFR_SINGLE_LONG_FUNCTION(name) \
849
881
  VALUE r_gmpfr_##name(int argc, VALUE *argv, VALUE self) \
850
882
  { \
851
883
  MP_FLOAT *self_val, *res_val; \
@@ -861,11 +893,35 @@ VALUE r_gmpfr_##name(int argc, VALUE *argv, VALUE self) \
861
893
  if (NIL_P (res_prec)) { res_prec_value = prec; } \
862
894
  else { res_prec_value = FIX2INT (res_prec); } \
863
895
  mpf_make_struct_init (res, res_val, res_prec_value); \
864
- mpfr_##name (res_val, arg1_val, self_val, __gmp_default_rounding_mode); \
896
+ mpfr_##name (res_val, arg1_val, self_val, __gmp_default_rounding_mode); \
865
897
  \
866
898
  return res; \
867
899
  }
868
900
 
901
+ #define MPFR_SINGLE_MPF_FUNCTION(name) \
902
+ VALUE r_gmpfr_##name(int argc, VALUE *argv, VALUE self) \
903
+ { \
904
+ MP_FLOAT *self_val, *arg1_val, *res_val; \
905
+ VALUE arg1, rnd_mode, res_prec; \
906
+ mpfr_prec_t prec, arg1_prec, res_prec_value; \
907
+ VALUE res; \
908
+ mp_rnd_t rnd_mode_val; \
909
+ \
910
+ rb_scan_args (argc, argv, "12", &arg1, &rnd_mode, &res_prec); \
911
+ \
912
+ mpf_get_struct_prec (self, self_val, prec); \
913
+ if (!GMPF_P (arg1)) { typeerror(FD); } \
914
+ mpf_get_struct_prec (arg1, arg1_val, arg1_prec); \
915
+ if (NIL_P (rnd_mode)) { rnd_mode_val = __gmp_default_rounding_mode; } \
916
+ else { rnd_mode_val = r_get_rounding_mode(rnd_mode); } \
917
+ if (NIL_P (res_prec)) { res_prec_value = prec; } \
918
+ else { res_prec_value = FIX2INT (res_prec); } \
919
+ mpf_make_struct_init (res, res_val, res_prec_value); \
920
+ mpfr_##name (res_val, arg1_val, self_val, rnd_mode_val); \
921
+ \
922
+ return res; \
923
+ }
924
+
869
925
  #define MPFR_SINGLE_BOOLEAN_FUNCTION(name) \
870
926
  static VALUE r_gmpfr_##name(VALUE self) \
871
927
  { \
@@ -879,17 +935,26 @@ static VALUE r_gmpfr_##name(VALUE self) \
879
935
  }
880
936
 
881
937
 
882
- #define MPFR_CONST_FUNCTION(name) \
883
- VALUE r_gmpfrsg_##name() \
884
- { \
885
- MP_FLOAT *res_val; \
886
- VALUE res; \
887
- \
888
- mpf_make_struct (res, res_val); \
889
- mpf_init (res_val); \
890
- mpfr_##name (res_val, __gmp_default_rounding_mode); \
891
- \
892
- return res; \
938
+ #define MPFR_CONST_FUNCTION(name) \
939
+ VALUE r_gmpfrsg_##name(int argc, VALUE *argv, VALUE self) \
940
+ { \
941
+ (void)self; \
942
+ MP_FLOAT *res_val; \
943
+ VALUE res; \
944
+ VALUE rnd_mode, prec; \
945
+ mp_rnd_t rnd_mode_val; \
946
+ mpfr_prec_t prec_val; \
947
+ \
948
+ rb_scan_args (argc, argv, "02", &rnd_mode, &prec); \
949
+ \
950
+ if (NIL_P (rnd_mode)) { rnd_mode_val = __gmp_default_rounding_mode; } \
951
+ else { rnd_mode_val = r_get_rounding_mode(rnd_mode); } \
952
+ if (NIL_P (prec)) { prec_val = mpfr_get_default_prec(); } \
953
+ else { prec_val = FIX2INT (prec); } \
954
+ mpf_make_struct_init (res, res_val, prec_val); \
955
+ mpfr_##name (res_val, rnd_mode_val); \
956
+ \
957
+ return res; \
893
958
  }
894
959
 
895
960
  MPFR_SINGLE_FUNCTION(sqrt)
@@ -905,18 +970,18 @@ MPFR_SINGLE_FUNCTION(exp10)
905
970
  MPFR_SINGLE_FUNCTION(cos)
906
971
  MPFR_SINGLE_FUNCTION(sin)
907
972
  MPFR_SINGLE_FUNCTION(tan)
973
+ MPFR_DOUBLE_FUNCTION(sin_cos)
908
974
  MPFR_SINGLE_FUNCTION(sec)
909
975
  MPFR_SINGLE_FUNCTION(csc)
910
976
  MPFR_SINGLE_FUNCTION(cot)
911
-
912
977
  MPFR_SINGLE_FUNCTION(acos)
913
978
  MPFR_SINGLE_FUNCTION(asin)
914
979
  MPFR_SINGLE_FUNCTION(atan)
915
-
980
+ MPFR_SINGLE_MPF_FUNCTION(atan2)
916
981
  MPFR_SINGLE_FUNCTION(cosh)
917
982
  MPFR_SINGLE_FUNCTION(sinh)
918
983
  MPFR_SINGLE_FUNCTION(tanh)
919
-
984
+ MPFR_DOUBLE_FUNCTION(sinh_cosh)
920
985
  MPFR_SINGLE_FUNCTION(sech)
921
986
  MPFR_SINGLE_FUNCTION(csch)
922
987
  MPFR_SINGLE_FUNCTION(coth)
@@ -939,10 +1004,13 @@ MPFR_SINGLE_FUNCTION(erf)
939
1004
  MPFR_SINGLE_FUNCTION(erfc)
940
1005
  MPFR_SINGLE_FUNCTION(j0)
941
1006
  MPFR_SINGLE_FUNCTION(j1)
942
- MPFR_SINGLE_1ARG_FUNCTION(jn)
1007
+ MPFR_SINGLE_LONG_FUNCTION(jn)
943
1008
  MPFR_SINGLE_FUNCTION(y0)
944
1009
  MPFR_SINGLE_FUNCTION(y1)
945
- MPFR_SINGLE_1ARG_FUNCTION(yn)
1010
+ MPFR_SINGLE_LONG_FUNCTION(yn)
1011
+
1012
+ MPFR_SINGLE_MPF_FUNCTION(agm)
1013
+ MPFR_SINGLE_MPF_FUNCTION(hypot)
946
1014
 
947
1015
  MPFR_CONST_FUNCTION(const_log2)
948
1016
  MPFR_CONST_FUNCTION(const_pi)
@@ -1010,32 +1078,84 @@ static VALUE r_gmpfr_pow(VALUE self, VALUE arg)
1010
1078
  return res;
1011
1079
  }
1012
1080
 
1013
- #endif
1014
-
1015
-
1016
1081
  /**********************************************************************
1017
- * _unsorted_ *
1082
+ * Rounding Related Functions *
1018
1083
  **********************************************************************/
1019
1084
 
1020
- DEFUN_FLOAT2FLOAT(floor,mpf_floor)
1021
- DEFUN_FLOAT2FLOAT(trunc,mpf_trunc)
1022
- DEFUN_FLOAT2FLOAT(ceil,mpf_ceil)
1085
+ VALUE r_gmpfsg_get_default_rounding_mode(VALUE klass)
1086
+ {
1087
+ (void)klass;
1088
+ const char *rounding_string_val;
1089
+ rounding_string_val = mpfr_print_rnd_mode (mpfr_get_default_rounding_mode ());
1090
+ if ( rounding_string_val == NULL ) {
1091
+ return Qnil;
1092
+ }
1093
+ else {
1094
+ return rb_const_get (mGMP, rb_intern (rounding_string_val));
1095
+ }
1096
+ }
1023
1097
 
1024
- /*
1025
- * call-seq:
1026
- * float.sgn
1027
- *
1028
- * From the GMP Manual:
1029
- *
1030
- * Returns +1 if +float+ > 0, 0 if +float+ == 0, and -1 if +float+ < 0.
1031
- */
1032
- VALUE r_gmpf_sgn(VALUE self)
1098
+ VALUE r_gmpfsg_set_default_rounding_mode(VALUE klass, VALUE arg)
1099
+ {
1100
+ (void)klass;
1101
+ VALUE mode;
1102
+ if (GMPRND_P(arg)) {
1103
+ mode = rb_funcall (arg, rb_intern("mode"), 0);
1104
+ if (FIX2INT(mode) < 0 || FIX2INT(mode) > 3) {
1105
+ rb_raise(rb_eRangeError, "rounding mode must be one of the rounding mode constants.");
1106
+ }
1107
+ } else {
1108
+ rb_raise(rb_eTypeError, "rounding mode must be one of the rounding mode constants.");
1109
+ }
1110
+
1111
+ switch (FIX2INT(mode)) {
1112
+ case 0:
1113
+ mpfr_set_default_rounding_mode (GMP_RNDN); break;
1114
+ case 1:
1115
+ mpfr_set_default_rounding_mode (GMP_RNDZ); break;
1116
+ case 2:
1117
+ mpfr_set_default_rounding_mode (GMP_RNDU); break;
1118
+ case 3:
1119
+ mpfr_set_default_rounding_mode (GMP_RNDD); break;
1120
+ #if MPFR_VERSION_MAJOR>2
1121
+ case 4:
1122
+ mpfr_set_default_rounding_mode (MPFR_RNDA); break;
1123
+ #endif
1124
+ }
1125
+
1126
+ return Qnil;
1127
+ }
1128
+
1129
+ VALUE r_gmpf_can_round(VALUE self, VALUE err, VALUE rnd1, VALUE rnd2, VALUE prec)
1033
1130
  {
1034
1131
  MP_FLOAT *self_val;
1035
- mpf_get_struct (self, self_val);
1036
- return INT2FIX (mpf_sgn (self_val));
1132
+ mp_exp_t err_val;
1133
+ mpfr_rnd_t rnd1_val, rnd2_val;
1134
+ mpfr_prec_t prec_val;
1135
+
1136
+ mpf_get_struct(self, self_val);
1137
+ if (FIXNUM_P(err)) {
1138
+ err_val = FIX2INT(err);
1139
+ } else {
1140
+ typeerror_as(X, "err");
1141
+ }
1142
+ rnd1_val = r_get_rounding_mode(rnd1);
1143
+ rnd2_val = r_get_rounding_mode(rnd2);
1144
+ prec_val = FIX2INT (prec);
1145
+
1146
+ if (mpfr_can_round (self_val, err_val, rnd1_val, rnd2_val, prec_val))
1147
+ return Qtrue;
1148
+ else
1149
+ return Qfalse;
1037
1150
  }
1038
1151
 
1152
+ #endif
1153
+
1154
+
1155
+ /**********************************************************************
1156
+ * _unsorted_ *
1157
+ **********************************************************************/
1158
+
1039
1159
  VALUE r_gmpf_get_prec(VALUE self)
1040
1160
  {
1041
1161
  MP_FLOAT *self_val;
@@ -1162,37 +1282,33 @@ void init_gmpf()
1162
1282
  //"unordered", r_gmpfr_unordered_p
1163
1283
 
1164
1284
  // Special Functions
1165
- rb_define_method(cGMP_F, "log", r_gmpfr_log, -1);
1166
- rb_define_method(cGMP_F, "log2", r_gmpfr_log2, -1);
1167
- rb_define_method(cGMP_F, "log10", r_gmpfr_log10, -1);
1168
- rb_define_method(cGMP_F, "exp", r_gmpfr_exp, -1);
1169
- rb_define_method(cGMP_F, "exp2", r_gmpfr_exp2, -1);
1170
- rb_define_method(cGMP_F, "exp10", r_gmpfr_exp10, -1);
1171
- rb_define_method(cGMP_F, "cos", r_gmpfr_cos, -1);
1172
- rb_define_method(cGMP_F, "sin", r_gmpfr_sin, -1);
1173
- rb_define_method(cGMP_F, "tan", r_gmpfr_tan, -1);
1174
- // "sin_cos", r_gmpfr_sin_cos
1175
- rb_define_method(cGMP_F, "sec", r_gmpfr_sec, -1);
1176
- rb_define_method(cGMP_F, "csc", r_gmpfr_csc, -1);
1177
- rb_define_method(cGMP_F, "cot", r_gmpfr_cot, -1);
1178
-
1179
- rb_define_method(cGMP_F, "acos", r_gmpfr_acos, -1);
1180
- rb_define_method(cGMP_F, "asin", r_gmpfr_asin, -1);
1181
- rb_define_method(cGMP_F, "atan", r_gmpfr_atan, -1);
1182
- // "atan2", r_gmpfr_atan2
1183
-
1184
- rb_define_method(cGMP_F, "cosh", r_gmpfr_cosh, -1);
1185
- rb_define_method(cGMP_F, "sinh", r_gmpfr_sinh, -1);
1186
- rb_define_method(cGMP_F, "tanh", r_gmpfr_tanh, -1);
1187
-
1188
- // "sinh_cosh", r_gmpfr_sinh_cosh
1189
-
1190
- rb_define_method(cGMP_F, "sech", r_gmpfr_sech, -1);
1191
- rb_define_method(cGMP_F, "csch", r_gmpfr_csch, -1);
1192
- rb_define_method(cGMP_F, "coth", r_gmpfr_coth, -1);
1193
- rb_define_method(cGMP_F, "acosh", r_gmpfr_acosh, -1);
1194
- rb_define_method(cGMP_F, "asinh", r_gmpfr_asinh, -1);
1195
- rb_define_method(cGMP_F, "atanh", r_gmpfr_atanh, -1);
1285
+ rb_define_method(cGMP_F, "log", r_gmpfr_log, -1);
1286
+ rb_define_method(cGMP_F, "log2", r_gmpfr_log2, -1);
1287
+ rb_define_method(cGMP_F, "log10", r_gmpfr_log10, -1);
1288
+ rb_define_method(cGMP_F, "exp", r_gmpfr_exp, -1);
1289
+ rb_define_method(cGMP_F, "exp2", r_gmpfr_exp2, -1);
1290
+ rb_define_method(cGMP_F, "exp10", r_gmpfr_exp10, -1);
1291
+ rb_define_method(cGMP_F, "cos", r_gmpfr_cos, -1);
1292
+ rb_define_method(cGMP_F, "sin", r_gmpfr_sin, -1);
1293
+ rb_define_method(cGMP_F, "tan", r_gmpfr_tan, -1);
1294
+ rb_define_method(cGMP_F, "sin_cos", r_gmpfr_sin_cos, -1);
1295
+ rb_define_method(cGMP_F, "sec", r_gmpfr_sec, -1);
1296
+ rb_define_method(cGMP_F, "csc", r_gmpfr_csc, -1);
1297
+ rb_define_method(cGMP_F, "cot", r_gmpfr_cot, -1);
1298
+ rb_define_method(cGMP_F, "acos", r_gmpfr_acos, -1);
1299
+ rb_define_method(cGMP_F, "asin", r_gmpfr_asin, -1);
1300
+ rb_define_method(cGMP_F, "atan", r_gmpfr_atan, -1);
1301
+ rb_define_method(cGMP_F, "atan2", r_gmpfr_atan2, -1);
1302
+ rb_define_method(cGMP_F, "cosh", r_gmpfr_cosh, -1);
1303
+ rb_define_method(cGMP_F, "sinh", r_gmpfr_sinh, -1);
1304
+ rb_define_method(cGMP_F, "tanh", r_gmpfr_tanh, -1);
1305
+ rb_define_method(cGMP_F, "sinh_cosh", r_gmpfr_sinh_cosh, -1);
1306
+ rb_define_method(cGMP_F, "sech", r_gmpfr_sech, -1);
1307
+ rb_define_method(cGMP_F, "csch", r_gmpfr_csch, -1);
1308
+ rb_define_method(cGMP_F, "coth", r_gmpfr_coth, -1);
1309
+ rb_define_method(cGMP_F, "acosh", r_gmpfr_acosh, -1);
1310
+ rb_define_method(cGMP_F, "asinh", r_gmpfr_asinh, -1);
1311
+ rb_define_method(cGMP_F, "atanh", r_gmpfr_atanh, -1);
1196
1312
 
1197
1313
  // "fac", r_gmpfr_fac
1198
1314
 
@@ -1218,17 +1334,22 @@ void init_gmpf()
1218
1334
 
1219
1335
  // "fma", r_gmpfr_fma
1220
1336
  // "fms", r_gmpfr_fms
1221
- // "agm", r_gmpfr_agm
1222
- // "hypot", r_gmpfr_hypot
1337
+ rb_define_method(cGMP_F, "agm", r_gmpfr_agm, -1);
1338
+ rb_define_method(cGMP_F, "hypot", r_gmpfr_hypot, -1);
1223
1339
  // "ai", r_gmpfr_ai !! 3.0.0
1224
1340
 
1225
- rb_define_singleton_method(cGMP_F, "const_log2", r_gmpfrsg_const_log2, 0);
1226
- rb_define_singleton_method(cGMP_F, "const_pi", r_gmpfrsg_const_pi, 0);
1227
- rb_define_singleton_method(cGMP_F, "const_euler", r_gmpfrsg_const_euler, 0);
1228
- rb_define_singleton_method(cGMP_F, "const_catalan", r_gmpfrsg_const_catalan, 0);
1341
+ rb_define_singleton_method(cGMP_F, "const_log2", r_gmpfrsg_const_log2, -1);
1342
+ rb_define_singleton_method(cGMP_F, "const_pi", r_gmpfrsg_const_pi, -1);
1343
+ rb_define_singleton_method(cGMP_F, "const_euler", r_gmpfrsg_const_euler, -1);
1344
+ rb_define_singleton_method(cGMP_F, "const_catalan", r_gmpfrsg_const_catalan, -1);
1229
1345
 
1230
1346
  // Integer and Remainder Related Functions
1231
1347
  // "integer?", r_gmpfr_integer_p
1348
+
1349
+ // Rounding Related Functions
1350
+ rb_define_singleton_method (cGMP_F, "default_rounding_mode", r_gmpfsg_get_default_rounding_mode, 0);
1351
+ rb_define_singleton_method (cGMP_F, "default_rounding_mode=", r_gmpfsg_set_default_rounding_mode, 1);
1352
+ rb_define_method(cGMP_F, "can_round?", r_gmpf_can_round, 4);
1232
1353
  #endif /* MPFR */
1233
1354
 
1234
1355
  // _unsorted_