gmp 0.4.1 → 0.4.3

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG CHANGED
@@ -1,6 +1,20 @@
1
+ 0.4.3:
2
+ * Support for MPFR on Windows introduced. gmp-x86-mswin32 gem should be used.
3
+ * Removed compilation warnings when using MPFR
4
+ * Added constants GMP::GMP_CC, GMP::GMP_CFLAGS, and GMP::GMP_BITS_PER_LIMB.
5
+ * Added constant GMP::MPFR_VERSION.
6
+ * Added MPFR rounding constants. These will be changed soon though.
7
+ * Added MPFR tests adapted straight from the MPFR library, just tsqrt so far.
8
+ * Added 3x MPFR functions: sec(), csc(), cot().
9
+ * Added function existence tests from
10
+ * Unit test results: 78 tests, 1025 assertions, 0 failures, 0 errors
11
+ * Unit test results: 72 tests, 593 assertions, 0 failures, 0 errors (w/o MPFR)
12
+
1
13
  0.4.1:
2
14
  * Fixed some gem dates
15
+ * Fixed gmp.so in x86-mswin32 gem
3
16
  * Added urandomm(), documentation, and tests.
17
+ * Unit test results: 70 tests, 577 assertions, 0 failures, 0 errors
4
18
 
5
19
  0.4.0:
6
20
  * Support for Windows introduced. gmp-x86-mswin32 gem should be used.
@@ -63,7 +63,8 @@ by me: gmp gem 0.4.0 on:
63
63
  | | (MRI) Ruby 1.9.1 | |
64
64
  +-------------------------------------+-------------------+-----------+
65
65
 
66
- <b>Note:</b> To get this running on Mac OS X (32-bit), I compiled GMP 4.3.1 with:
66
+ <b>Note:</b> To get this running on Mac OS X (32-bit), I compiled GMP 4.3.1
67
+ with:
67
68
  ./configure ABI=32 --disable-dependency-tracking
68
69
 
69
70
  =Authors
@@ -71,9 +72,25 @@ by me: gmp gem 0.4.0 on:
71
72
  * Tomasz Wegrzanowski
72
73
  * srawlins
73
74
 
75
+ =Constants
76
+
77
+ The GMP module includes the following constants. Mathematical constants, such
78
+ as pi, are defined under class methods of GMP::F, listed below.
79
+
80
+ GMP::GMP_VERSION #=> A string like "5.0.1"
81
+ GMP::GMP_CC #=> The compiler used to compile GMP
82
+ GMP::GMP_CFLAGS #=> The CFLAGS used to compile GMP
83
+ GMP::GMP_BITS_PER_LIMB #=> The number of bits per limb
84
+ (if MPFR is available)
85
+ GMP::MPFR_VERSION #=> A string like "2.4.2"
86
+ GMP::GMP_RNDN #=> The constant representing "round to nearest"
87
+ GMP::GMP_RNDZ #=> The constant representing "round toward zero"
88
+ GMP::GMP_RNDU #=> The constant representing "round toward plus infinity"
89
+ GMP::GMP_RNDD #=> The constant representing "round toward minus infinity"
90
+
74
91
  =Classes
75
92
 
76
- The module GMP is provided with following classes:
93
+ The GMP module is provided with following classes:
77
94
  * GMP::Z - infinite precision integer numbers
78
95
  * GMP::Q - infinite precision rational numbers
79
96
  * GMP::F - arbitrary precision floating point numbers
@@ -190,19 +207,39 @@ You can also call them as:
190
207
  prec get precision
191
208
  floor,ceil,trunc nearest integer, GMP::F is returned, not GMP::Z
192
209
  floor!,ceil!,trunc! in-place nearest integer
193
- GMP::F (only if MPFR is available)
194
- exp e^object
195
- expm1 the same as (object.exp) - 1, with better
196
- precision
210
+ GMP::RandState
211
+ seed(integer) seed the generator with a Fixnum or GMP::Z
212
+ urandomb(fixnum) get uniformly distributed random number between 0
213
+ and 2^fixnum-1, inclusive
214
+ urandomm(integer) get uniformly distributed random number between 0
215
+ and integer-1, inclusive
216
+ GMP (timing functions for GMPbench (0.2))
217
+ cputime milliseconds of cpu time since Ruby start
218
+ time times the execution of a block
219
+
220
+ *only if MPFR is available*
221
+ class methods of GMP::F
222
+ const_log2 returns the natural log of 2
223
+ const_pi returns pi
224
+ const_euler returns euler
225
+ const_catalan returns catalan
226
+ GMP::F
227
+ sqrt square root of the object
228
+ ** power
197
229
  log natural logarithm of object
198
230
  log2 binary logarithm of object
199
231
  log10 decimal logarithm of object
232
+ exp e^object
200
233
  log1p the same as (object + 1).log, with better
201
234
  precision
202
- sqrt square root of the object
235
+ expm1 the same as (object.exp) - 1, with better
236
+ precision
203
237
  cos \
204
238
  sin |
205
239
  tan |
240
+ sec |
241
+ csc |
242
+ cot |
206
243
  acos |
207
244
  asin |
208
245
  atan | trigonometric functions
@@ -216,14 +253,9 @@ You can also call them as:
216
253
  infinite? | type of floating point number
217
254
  finite? |
218
255
  number? /
219
- ** power
220
256
  GMP::RandState
221
- seed(integer) seed the generator with a Fixnum or GMP::Z
222
- urandomb(fixnum) get uniformly distributed random number between 0
223
- and 2^fixnum-1, inclusive
224
- GMP (timing functions for GMPbench (0.2))
225
- cputime milliseconds of cpu time since Ruby start
226
- time times the execution of a block
257
+ mpfr_urandomb(fixnum) get uniformly distributed random floating-point
258
+ number within 0 <= rop < 1
227
259
 
228
260
 
229
261
  =Testing
@@ -251,8 +283,9 @@ If there is no explicit precision, highest precision of all GMP::F arguments is
251
283
  used. That doesn't ensure that result will be exact. For details, consult any
252
284
  paper about floating point arithmetics.
253
285
 
254
- Default precision can be explicitely set by passing 0 to GMP::F.new(). In
255
- particular, you can set precision of copy of GMP::F object by:
286
+ Default precision can be explicitely set by passing 0 as the second argument
287
+ for to GMP::F.new(). In particular, you can set precision of copy of GMP::F
288
+ object by:
256
289
  new_obj = GMP::F.new(old_obj, 0)
257
290
 
258
291
  Precision argument, and default_precision will be rounded up to whatever GMP
@@ -331,7 +364,6 @@ These are inherited from Tomasz. I will go through these and see which are
331
364
  still relevant.
332
365
 
333
366
  * mpz_fits_* and 31 vs. 32 integer variables
334
- * all appropriate module and class methods if there are any to add
335
367
  * fix all sign issues (don't know what these are)
336
368
  * floats with precision control
337
369
  * to_s vs. inspect
data/ext/gmp.c CHANGED
@@ -121,6 +121,51 @@ static VALUE r_gmpfsg_set_default_prec(VALUE klass, VALUE arg)
121
121
  return Qnil;
122
122
  }
123
123
 
124
+ #ifdef MPFR
125
+ static VALUE r_gmpfsg_get_default_rounding_mode(VALUE klass)
126
+ {
127
+ (void)klass;
128
+ const char *rounding_string_val;
129
+ VALUE rounding_string;
130
+ ID method_to_sym = rb_intern("to_sym");
131
+ rounding_string_val = mpfr_print_rnd_mode (mpfr_get_default_rounding_mode ());
132
+ rounding_string = rb_str_new2 (rounding_string_val);
133
+ /*return rb_const_get (mGMP, rb_intern (rounding_string));*/
134
+ return rb_funcall (rounding_string, method_to_sym, 0);
135
+ }
136
+
137
+ static VALUE r_gmpfsg_set_default_rounding_mode(VALUE klass, VALUE arg)
138
+ {
139
+ (void)klass;
140
+ int arg_val;
141
+ if (FIXNUM_P(arg)) {
142
+ arg_val = FIX2INT(arg);
143
+ if (arg_val < 0 || arg_val > 3) {
144
+ rb_raise(rb_eRangeError, "rounding mode must be one of the rounding mode constants.");
145
+ }
146
+ } else {
147
+ rb_raise(rb_eTypeError, "rounding mode must be one of the rounding mode constants.");
148
+ }
149
+
150
+ switch (arg_val) {
151
+ case 0:
152
+ mpfr_set_default_rounding_mode (GMP_RNDN);
153
+ break;
154
+ case 1:
155
+ mpfr_set_default_rounding_mode (GMP_RNDZ);
156
+ break;
157
+ case 2:
158
+ mpfr_set_default_rounding_mode (GMP_RNDU);
159
+ break;
160
+ case 3:
161
+ mpfr_set_default_rounding_mode (GMP_RNDD);
162
+ break;
163
+ }
164
+
165
+ return Qnil;
166
+ }
167
+ #endif /* MPFR */
168
+
124
169
  #include "gmpf.h"
125
170
  #include "gmpq.h"
126
171
  /* #include "gmpz.h" */
@@ -135,6 +180,18 @@ static VALUE r_gmpfsg_set_default_prec(VALUE klass, VALUE arg)
135
180
  void Init_gmp() {
136
181
  mGMP = rb_define_module("GMP");
137
182
  rb_define_const(mGMP, "GMP_VERSION", rb_str_new2(gmp_version));
183
+ rb_define_const(mGMP, "GMP_CC", rb_str_new2(__GMP_CC));
184
+ rb_define_const(mGMP, "GMP_CFLAGS", rb_str_new2(__GMP_CFLAGS));
185
+ rb_define_const(mGMP, "GMP_BITS_PER_LIMB", INT2FIX(mp_bits_per_limb));
186
+ #ifdef MPFR
187
+ rb_define_const(mGMP, "MPFR_VERSION", rb_str_new2(MPFR_VERSION_STRING));
188
+ rb_define_const(mGMP, "MPFR_PREC_MIN", INT2FIX(MPFR_PREC_MIN));
189
+ rb_define_const(mGMP, "MPFR_PREC_MAX", INT2FIX(MPFR_PREC_MAX));
190
+ rb_define_const(mGMP, "GMP_RNDN", INT2FIX(0));
191
+ rb_define_const(mGMP, "GMP_RNDZ", INT2FIX(1));
192
+ rb_define_const(mGMP, "GMP_RNDU", INT2FIX(2));
193
+ rb_define_const(mGMP, "GMP_RNDD", INT2FIX(3));
194
+ #endif /* MPFR */
138
195
 
139
196
  cGMP_Z = rb_define_class_under(mGMP, "Z", rb_cInteger);
140
197
  init_gmpz();
@@ -149,8 +206,12 @@ void Init_gmp() {
149
206
 
150
207
  cGMP_F = rb_define_class_under (mGMP, "F", rb_cNumeric);
151
208
  init_gmpf();
152
- rb_define_singleton_method(cGMP_F, "default_prec", r_gmpfsg_get_default_prec, 0);
153
- rb_define_singleton_method(cGMP_F, "default_prec=", r_gmpfsg_set_default_prec, 1);
209
+ rb_define_singleton_method (cGMP_F, "default_prec", r_gmpfsg_get_default_prec, 0);
210
+ rb_define_singleton_method (cGMP_F, "default_prec=", r_gmpfsg_set_default_prec, 1);
211
+ #ifdef MPFR
212
+ rb_define_singleton_method (cGMP_F, "default_rounding_mode", r_gmpfsg_get_default_rounding_mode, 0);
213
+ rb_define_singleton_method (cGMP_F, "default_rounding_mode=", r_gmpfsg_set_default_rounding_mode, 1);
214
+ #endif /* MPFR */
154
215
  rb_define_method(cGMP_F, "coerce", r_gmpf_coerce, 1); // new method - testing
155
216
 
156
217
  /* rb_define_method(cGMP_F, "cmpabs", r_gmpf_cmpabs, 1);*/
@@ -160,34 +221,6 @@ void Init_gmp() {
160
221
 
161
222
  init_gmpbench_timing();
162
223
 
163
- #ifdef MPFR
164
- rb_define_method(cGMP_F, "exp", r_gmpfr_exp, 0);
165
- rb_define_method(cGMP_F, "log", r_gmpfr_log, 0);
166
- rb_define_method(cGMP_F, "sqrt", r_gmpfr_sqrt, 0);
167
- rb_define_method(cGMP_F, "cos", r_gmpfr_cos, 0);
168
- rb_define_method(cGMP_F, "sin", r_gmpfr_sin, 0);
169
- rb_define_method(cGMP_F, "tan", r_gmpfr_tan, 0);
170
- rb_define_method(cGMP_F, "acos", r_gmpfr_acos, 0);
171
- rb_define_method(cGMP_F, "asin", r_gmpfr_asin, 0);
172
- rb_define_method(cGMP_F, "atan", r_gmpfr_atan, 0);
173
- rb_define_method(cGMP_F, "cosh", r_gmpfr_cosh, 0);
174
- rb_define_method(cGMP_F, "sinh", r_gmpfr_sinh, 0);
175
- rb_define_method(cGMP_F, "tanh", r_gmpfr_tanh, 0);
176
- rb_define_method(cGMP_F, "acosh", r_gmpfr_acosh, 0);
177
- rb_define_method(cGMP_F, "asinh", r_gmpfr_asinh, 0);
178
- rb_define_method(cGMP_F, "atanh", r_gmpfr_atanh, 0);
179
- rb_define_method(cGMP_F, "log1p", r_gmpfr_log1p, 0);
180
- rb_define_method(cGMP_F, "expm1", r_gmpfr_expm1, 0);
181
- rb_define_method(cGMP_F, "log2", r_gmpfr_log2, 0);
182
- rb_define_method(cGMP_F, "log10", r_gmpfr_log10, 0);
183
-
184
- rb_define_method(cGMP_F, "nan?", r_gmpfr_nan_p, 0);
185
- rb_define_method(cGMP_F, "infinite?", r_gmpfr_inf_p, 0);
186
- rb_define_method(cGMP_F, "finite?", r_gmpfr_fin_p, 0);
187
- rb_define_method(cGMP_F, "number?", r_gmpfr_number_p, 0);
188
-
189
- rb_define_method(cGMP_F, "**", r_gmpfr_pow, 1);
190
- #endif /* MPFR */
191
224
  // more
192
225
 
193
226
  REGISTER_TAKEOVER(and, "&", "old_and")
data/ext/gmpf.c CHANGED
@@ -105,7 +105,7 @@ VALUE r_gmpf_initialize(int argc, VALUE *argv, VALUE self)
105
105
  else
106
106
  rb_raise(rb_eRangeError, "prec must be non-negative");
107
107
  } else {
108
- rb_raise(rb_eTypeError, "prec must be FixNum");
108
+ rb_raise(rb_eTypeError, "prec must be a Fixnum");
109
109
  }
110
110
  } else if (GMPF_P(arg)) {
111
111
  mpf_get_struct (arg, arg_val_f);
@@ -515,6 +515,166 @@ DEFUN_FLOAT_CMP(gt,>)
515
515
  DEFUN_FLOAT_CMP(ge,>=)
516
516
 
517
517
 
518
+ #ifdef MPFR
519
+
520
+ #define MPFR_SINGLE_FUNCTION(name) \
521
+ VALUE r_gmpfr_##name(VALUE self) \
522
+ { \
523
+ MP_FLOAT *self_val, *res_val; \
524
+ unsigned long prec; \
525
+ VALUE res; \
526
+ \
527
+ mpf_get_struct_prec (self, self_val, prec); \
528
+ mpf_make_struct_init (res, res_val, prec); \
529
+ mpfr_##name (res_val, self_val, __gmp_default_rounding_mode); \
530
+ \
531
+ return res; \
532
+ }
533
+
534
+ #define MPFR_CONST_FUNCTION(name) \
535
+ VALUE r_gmpfrsg_##name() \
536
+ { \
537
+ MP_FLOAT *res_val; \
538
+ VALUE res; \
539
+ \
540
+ mpf_make_struct (res, res_val); \
541
+ mpf_init (res_val); \
542
+ mpfr_##name (res_val, __gmp_default_rounding_mode); \
543
+ \
544
+ return res; \
545
+ }
546
+
547
+ MPFR_SINGLE_FUNCTION(sqrt)
548
+
549
+ MPFR_SINGLE_FUNCTION(log)
550
+ MPFR_SINGLE_FUNCTION(log2)
551
+ MPFR_SINGLE_FUNCTION(log10)
552
+ MPFR_SINGLE_FUNCTION(exp)
553
+
554
+ MPFR_SINGLE_FUNCTION(cos)
555
+ MPFR_SINGLE_FUNCTION(sin)
556
+ MPFR_SINGLE_FUNCTION(tan)
557
+ MPFR_SINGLE_FUNCTION(sec)
558
+ MPFR_SINGLE_FUNCTION(csc)
559
+ MPFR_SINGLE_FUNCTION(cot)
560
+
561
+ MPFR_SINGLE_FUNCTION(acos)
562
+ MPFR_SINGLE_FUNCTION(asin)
563
+ MPFR_SINGLE_FUNCTION(atan)
564
+
565
+ MPFR_SINGLE_FUNCTION(cosh)
566
+ MPFR_SINGLE_FUNCTION(sinh)
567
+ MPFR_SINGLE_FUNCTION(tanh)
568
+
569
+ MPFR_SINGLE_FUNCTION(acosh)
570
+ MPFR_SINGLE_FUNCTION(asinh)
571
+ MPFR_SINGLE_FUNCTION(atanh)
572
+
573
+ MPFR_SINGLE_FUNCTION(log1p)
574
+ MPFR_SINGLE_FUNCTION(expm1)
575
+
576
+ MPFR_CONST_FUNCTION(const_log2)
577
+ MPFR_CONST_FUNCTION(const_pi)
578
+ MPFR_CONST_FUNCTION(const_euler)
579
+ MPFR_CONST_FUNCTION(const_catalan)
580
+
581
+ static VALUE r_gmpfr_nan_p(VALUE self)
582
+ {
583
+ MP_FLOAT *self_val;
584
+
585
+ mpf_get_struct(self, self_val);
586
+ if (mpfr_nan_p(self_val)) {
587
+ return Qtrue;
588
+ }
589
+ else {
590
+ return Qfalse;
591
+ }
592
+ }
593
+
594
+ static VALUE r_gmpfr_inf_p(VALUE self)
595
+ {
596
+ MP_FLOAT *self_val;
597
+
598
+ mpf_get_struct(self, self_val);
599
+ if (mpfr_inf_p(self_val)) {
600
+ return Qtrue;
601
+ }
602
+ else {
603
+ return Qfalse;
604
+ }
605
+ }
606
+
607
+ static VALUE r_gmpfr_fin_p(VALUE self)
608
+ {
609
+ if (r_gmpfr_inf_p(self)) {
610
+ return Qfalse;
611
+ }
612
+ else {
613
+ return Qtrue;
614
+ }
615
+ }
616
+
617
+ static VALUE r_gmpfr_number_p(VALUE self)
618
+ {
619
+ MP_FLOAT *self_val;
620
+
621
+ mpf_get_struct(self, self_val);
622
+ if (mpfr_number_p(self_val)) {
623
+ return Qtrue;
624
+ }
625
+ else {
626
+ return Qfalse;
627
+ }
628
+ }
629
+
630
+ static VALUE r_gmpfr_pow(VALUE self, VALUE arg)
631
+ {
632
+ MP_FLOAT *self_val, *res_val, *arg_val_f;
633
+ MP_RAT *arg_val_q;
634
+ MP_INT *arg_val_z;
635
+ unsigned long prec;
636
+ VALUE res;
637
+
638
+ mpf_get_struct_prec(self, self_val, prec);
639
+
640
+ if (GMPF_P(arg)) {
641
+ mpf_get_struct(arg, arg_val_f);
642
+ prec_max(prec, arg_val_f);
643
+ mpf_make_struct_init(res, res_val, prec);
644
+ mpfr_pow(res_val, self_val, arg_val_f, __gmp_default_rounding_mode);
645
+ } else {
646
+ mpf_make_struct_init(res, res_val, prec);
647
+
648
+ if (GMPZ_P(arg)) {
649
+ mpz_get_struct(arg, arg_val_z);
650
+ mpf_set_z(res_val, arg_val_z);
651
+ mpfr_pow(res_val, self_val, res_val, __gmp_default_rounding_mode);
652
+ } else if (GMPQ_P(arg)) {
653
+ mpq_get_struct(arg, arg_val_q);
654
+ mpf_set_q(res_val, arg_val_q);
655
+ mpfr_pow(res_val, self_val, res_val, __gmp_default_rounding_mode);
656
+ } else if (FLOAT_P(arg)) {
657
+ mpf_set_d(res_val, NUM2DBL(arg));
658
+ mpfr_pow(res_val, self_val, res_val, __gmp_default_rounding_mode);
659
+ } else if (FIXNUM_P(arg)) {
660
+ mpfr_pow_si(res_val, self_val, FIX2INT(arg), __gmp_default_rounding_mode);
661
+ } else if (BIGNUM_P(arg)) {
662
+ mpz_temp_from_bignum(arg_val_z, arg);
663
+ mpf_set_z(res_val, arg_val_z);
664
+ mpz_temp_free(arg_val_z);
665
+ mpfr_pow(res_val, self_val, res_val, __gmp_default_rounding_mode);
666
+ } else {
667
+ typeerror(ZQFXBD);
668
+ }
669
+
670
+ }
671
+
672
+ return res;
673
+ }
674
+
675
+ #endif
676
+
677
+
518
678
  /**********************************************************************
519
679
  * _unsorted_ *
520
680
  **********************************************************************/
@@ -549,8 +709,6 @@ VALUE r_gmpf_get_prec(VALUE self)
549
709
  void init_gmpf()
550
710
  {
551
711
  mGMP = rb_define_module("GMP");
552
- // rb_define_module_function(mGMP, "Z", r_gmpmod_z, -1);
553
- // rb_define_module_function(mGMP, "Q", r_gmpmod_q, -1);
554
712
  rb_define_module_function(mGMP, "F", r_gmpmod_f, -1);
555
713
 
556
714
  cGMP_F = rb_define_class_under (mGMP, "F", rb_cNumeric);
@@ -583,6 +741,52 @@ void init_gmpf()
583
741
  rb_define_method(cGMP_F, "<=", r_gmpf_cmp_le, 1);
584
742
  rb_define_method(cGMP_F, "==", r_gmpf_eq, 1);
585
743
 
744
+ #ifdef MPFR
745
+ // Basic Arithmetic Functions
746
+ rb_define_method(cGMP_F, "sqrt", r_gmpfr_sqrt, 0);
747
+
748
+ rb_define_method(cGMP_F, "**", r_gmpfr_pow, 1);
749
+
750
+ // Comparison Functions
751
+ rb_define_method(cGMP_F, "nan?", r_gmpfr_nan_p, 0);
752
+ rb_define_method(cGMP_F, "infinite?", r_gmpfr_inf_p, 0);
753
+ rb_define_method(cGMP_F, "finite?", r_gmpfr_fin_p, 0);
754
+ rb_define_method(cGMP_F, "number?", r_gmpfr_number_p, 0);
755
+
756
+ // Special Functions
757
+ rb_define_method(cGMP_F, "log", r_gmpfr_log, 0);
758
+ rb_define_method(cGMP_F, "log2", r_gmpfr_log2, 0);
759
+ rb_define_method(cGMP_F, "log10", r_gmpfr_log10, 0);
760
+ rb_define_method(cGMP_F, "exp", r_gmpfr_exp, 0);
761
+
762
+ rb_define_method(cGMP_F, "cos", r_gmpfr_cos, 0);
763
+ rb_define_method(cGMP_F, "sin", r_gmpfr_sin, 0);
764
+ rb_define_method(cGMP_F, "tan", r_gmpfr_tan, 0);
765
+ rb_define_method(cGMP_F, "sec", r_gmpfr_sec, 0);
766
+ rb_define_method(cGMP_F, "csc", r_gmpfr_csc, 0);
767
+ rb_define_method(cGMP_F, "cot", r_gmpfr_cot, 0);
768
+
769
+ rb_define_method(cGMP_F, "acos", r_gmpfr_acos, 0);
770
+ rb_define_method(cGMP_F, "asin", r_gmpfr_asin, 0);
771
+ rb_define_method(cGMP_F, "atan", r_gmpfr_atan, 0);
772
+
773
+ rb_define_method(cGMP_F, "cosh", r_gmpfr_cosh, 0);
774
+ rb_define_method(cGMP_F, "sinh", r_gmpfr_sinh, 0);
775
+ rb_define_method(cGMP_F, "tanh", r_gmpfr_tanh, 0);
776
+
777
+ rb_define_method(cGMP_F, "acosh", r_gmpfr_acosh, 0);
778
+ rb_define_method(cGMP_F, "asinh", r_gmpfr_asinh, 0);
779
+ rb_define_method(cGMP_F, "atanh", r_gmpfr_atanh, 0);
780
+
781
+ rb_define_method(cGMP_F, "log1p", r_gmpfr_log1p, 0);
782
+ rb_define_method(cGMP_F, "expm1", r_gmpfr_expm1, 0);
783
+
784
+ rb_define_singleton_method(cGMP_F, "const_log2", r_gmpfrsg_const_log2, 0);
785
+ rb_define_singleton_method(cGMP_F, "const_pi", r_gmpfrsg_const_pi, 0);
786
+ rb_define_singleton_method(cGMP_F, "const_euler", r_gmpfrsg_const_euler, 0);
787
+ rb_define_singleton_method(cGMP_F, "const_catalan", r_gmpfrsg_const_catalan, 0);
788
+ #endif /* MPFR */
789
+
586
790
  // _unsorted_
587
791
  rb_define_method(cGMP_F, "floor", r_gmpf_floor, 0);
588
792
  rb_define_method(cGMP_F, "floor!", r_gmpf_floor_self, 0);
data/ext/gmpf.h CHANGED
@@ -9,136 +9,4 @@
9
9
 
10
10
  #include <ruby_gmp.h>
11
11
 
12
- #ifdef MPFR
13
- #define MPFR_SINGLE_FUNCTION(name) \
14
- static VALUE r_gmpfr_##name(VALUE self) \
15
- { \
16
- MP_FLOAT *self_val, *res_val; \
17
- unsigned long prec; \
18
- VALUE res; \
19
- \
20
- mpf_get_struct_prec(self, self_val, prec); \
21
- mpf_make_struct_init(res, res_val, prec); \
22
- mpfr_##name(res_val, self_val, __gmp_default_rounding_mode); \
23
- \
24
- return res; \
25
- }
26
-
27
- MPFR_SINGLE_FUNCTION(log)
28
- MPFR_SINGLE_FUNCTION(exp)
29
- MPFR_SINGLE_FUNCTION(sqrt)
30
- MPFR_SINGLE_FUNCTION(cos)
31
- MPFR_SINGLE_FUNCTION(sin)
32
- MPFR_SINGLE_FUNCTION(tan)
33
- MPFR_SINGLE_FUNCTION(acos)
34
- MPFR_SINGLE_FUNCTION(asin)
35
- MPFR_SINGLE_FUNCTION(atan)
36
- MPFR_SINGLE_FUNCTION(cosh)
37
- MPFR_SINGLE_FUNCTION(sinh)
38
- MPFR_SINGLE_FUNCTION(tanh)
39
- MPFR_SINGLE_FUNCTION(acosh)
40
- MPFR_SINGLE_FUNCTION(asinh)
41
- MPFR_SINGLE_FUNCTION(atanh)
42
- MPFR_SINGLE_FUNCTION(log1p)
43
- MPFR_SINGLE_FUNCTION(expm1)
44
- MPFR_SINGLE_FUNCTION(log2)
45
- MPFR_SINGLE_FUNCTION(log10)
46
-
47
- static VALUE r_gmpfr_nan_p(VALUE self)
48
- {
49
- MP_FLOAT *self_val;
50
-
51
- mpf_get_struct(self, self_val);
52
- if (mpfr_nan_p(self_val)) {
53
- return Qtrue;
54
- }
55
- else {
56
- return Qfalse;
57
- }
58
- }
59
-
60
- static VALUE r_gmpfr_inf_p(VALUE self)
61
- {
62
- MP_FLOAT *self_val;
63
-
64
- mpf_get_struct(self, self_val);
65
- if (mpfr_inf_p(self_val)) {
66
- return Qtrue;
67
- }
68
- else {
69
- return Qfalse;
70
- }
71
- }
72
-
73
- static VALUE r_gmpfr_fin_p(VALUE self)
74
- {
75
- if (r_gmpfr_inf_p(self)) {
76
- return Qfalse;
77
- }
78
- else {
79
- return Qtrue;
80
- }
81
- }
82
-
83
- static VALUE r_gmpfr_number_p(VALUE self)
84
- {
85
- MP_FLOAT *self_val;
86
-
87
- mpf_get_struct(self, self_val);
88
- if (mpfr_number_p(self_val)) {
89
- return Qtrue;
90
- }
91
- else {
92
- return Qfalse;
93
- }
94
- }
95
-
96
- static VALUE r_gmpfr_pow(VALUE self, VALUE arg)
97
- {
98
- MP_FLOAT *self_val, *res_val, *arg_val_f;
99
- MP_RAT *arg_val_q;
100
- MP_INT *arg_val_z;
101
- unsigned long prec;
102
- VALUE res;
103
-
104
- mpf_get_struct_prec(self, self_val, prec);
105
-
106
- if (GMPF_P(arg)) {
107
- mpf_get_struct(arg, arg_val_f);
108
- prec_max(prec, arg_val_f);
109
- mpf_make_struct_init(res, res_val, prec);
110
- mpfr_pow(res_val, self_val, arg_val_f, __gmp_default_rounding_mode);
111
- } else {
112
- mpf_make_struct_init(res, res_val, prec);
113
-
114
- if (GMPZ_P(arg)) {
115
- mpz_get_struct(arg, arg_val_z);
116
- mpf_set_z(res_val, arg_val_z);
117
- mpfr_pow(res_val, self_val, res_val, __gmp_default_rounding_mode);
118
- } else if (GMPQ_P(arg)) {
119
- mpq_get_struct(arg, arg_val_q);
120
- mpf_set_q(res_val, arg_val_q);
121
- mpfr_pow(res_val, self_val, res_val, __gmp_default_rounding_mode);
122
- } else if (FLOAT_P(arg)) {
123
- mpf_set_d(res_val, FLT2DBL(arg));
124
- mpfr_pow(res_val, self_val, res_val, __gmp_default_rounding_mode);
125
- } else if (FIXNUM_P(arg)) {
126
- mpfr_pow_si(res_val, self_val, FIX2INT(arg), __gmp_default_rounding_mode);
127
- } else if (BIGNUM_P(arg)) {
128
- mpz_temp_from_bignum(arg_val_z, arg);
129
- mpf_set_z(res_val, arg_val_z);
130
- mpz_temp_free(arg_val_z);
131
- mpfr_pow(res_val, self_val, res_val, __gmp_default_rounding_mode);
132
- } else {
133
- typeerror(ZQFXBD);
134
- }
135
-
136
- }
137
-
138
- return res;
139
- }
140
-
141
- #endif
142
-
143
-
144
12
  #endif
@@ -205,12 +205,13 @@ VALUE r_gmprandstate_urandomb(VALUE self, VALUE arg)
205
205
 
206
206
  /*
207
207
  * call-seq:
208
- * rand_state.urandomm(fixnum)
208
+ * rand_state.urandomm(integer)
209
209
  *
210
210
  * From the GMP Manual:
211
211
  *
212
212
  * Generate a uniformly distributed random integer in the range 0 to
213
- * fixnum-1, inclusive.
213
+ * _integer-1_, inclusive. _integer_ can be an instance of GMP::Z,
214
+ * Fixnum, or Bignum
214
215
  */
215
216
  VALUE r_gmprandstate_urandomm(VALUE self, VALUE arg)
216
217
  {
@@ -241,6 +242,54 @@ VALUE r_gmprandstate_urandomm(VALUE self, VALUE arg)
241
242
  return res;
242
243
  }
243
244
 
245
+
246
+ #ifdef MPFR
247
+ /**********************************************************************
248
+ * MPFR Random Numbers *
249
+ **********************************************************************/
250
+
251
+ /*
252
+ * call-seq:
253
+ * rand_state.mpfr_urandomb()
254
+ *
255
+ * From the MPFR Manual:
256
+ *
257
+ * Generate a uniformly distributed random float in the interval 0 <= rop < 1.
258
+ */
259
+ VALUE r_gmprandstate_mpfr_urandomb(int argc, VALUE *argv, VALUE self)
260
+ {
261
+ MP_RANDSTATE *self_val;
262
+ MP_FLOAT *res_val;
263
+ VALUE res;
264
+ unsigned long prec = 0;
265
+
266
+ if (argc > 1)
267
+ rb_raise (rb_eArgError, "wrong # of arguments(%d for 0 or 1)", argc);
268
+
269
+ mprandstate_get_struct (self,self_val);
270
+
271
+ if (argc == 1) {
272
+ if (FIXNUM_P (argv[0])) {
273
+ if (FIX2INT (argv[0]) >= 0)
274
+ prec = FIX2INT (argv[0]);
275
+ else
276
+ rb_raise (rb_eRangeError, "prec must be non-negative");
277
+ } else {
278
+ rb_raise (rb_eTypeError, "prec must be a Fixnum");
279
+ }
280
+ }
281
+
282
+ mpf_make_struct (res, res_val);
283
+ if (prec == 0) { mpf_init (res_val); }
284
+ else { mpf_init2 (res_val, prec); }
285
+
286
+ mpfr_urandomb (res_val, self_val);
287
+
288
+ return res;
289
+ }
290
+ #endif /* MPFR */
291
+
292
+
244
293
  void init_gmprandstate()
245
294
  {
246
295
  mGMP = rb_define_module("GMP");
@@ -258,4 +307,9 @@ void init_gmprandstate()
258
307
  // Integer Random Numbers
259
308
  rb_define_method(cGMP_RandState, "urandomb", r_gmprandstate_urandomb, 1);
260
309
  rb_define_method(cGMP_RandState, "urandomm", r_gmprandstate_urandomm, 1);
310
+
311
+ #ifdef MPFR
312
+ // Float Random Numbers
313
+ rb_define_method(cGMP_RandState, "mpfr_urandomb", r_gmprandstate_mpfr_urandomb, -1);
314
+ #endif /* MPFR */
261
315
  }
@@ -207,6 +207,40 @@ extern VALUE r_gmpf_eq(VALUE self, VALUE arg);
207
207
  extern VALUE r_gmpf_cmp(VALUE self, VALUE arg);
208
208
  extern int mpf_cmp_value(MP_FLOAT *OP, VALUE arg);
209
209
 
210
+ // MPFR
211
+ #ifdef MPFR
212
+ extern VALUE r_gmpfr_sqrt(VALUE self);
213
+
214
+ extern VALUE r_gmpfr_log(VALUE self);
215
+ extern VALUE r_gmpfr_log2(VALUE self);
216
+ extern VALUE r_gmpfr_log10(VALUE self);
217
+ extern VALUE r_gmpfr_exp(VALUE self);
218
+
219
+ extern VALUE r_gmpfr_cos(VALUE self);
220
+ extern VALUE r_gmpfr_sin(VALUE self);
221
+ extern VALUE r_gmpfr_tan(VALUE self);
222
+ extern VALUE r_gmpfr_sec(VALUE self);
223
+ extern VALUE r_gmpfr_csc(VALUE self);
224
+ extern VALUE r_gmpfr_cot(VALUE self);
225
+
226
+ extern VALUE r_gmpfr_acos(VALUE self);
227
+ extern VALUE r_gmpfr_asin(VALUE self);
228
+ extern VALUE r_gmpfr_atan(VALUE self);
229
+
230
+ extern VALUE r_gmpfr_cosh(VALUE self);
231
+ extern VALUE r_gmpfr_sinh(VALUE self);
232
+ extern VALUE r_gmpfr_tanh(VALUE self);
233
+
234
+ extern VALUE r_gmpfr_acosh(VALUE self);
235
+ extern VALUE r_gmpfr_asinh(VALUE self);
236
+ extern VALUE r_gmpfr_atanh(VALUE self);
237
+
238
+ extern VALUE r_gmpfrsg_const_log2();
239
+ extern VALUE r_gmpfrsg_const_pi();
240
+ extern VALUE r_gmpfrsg_const_euler();
241
+ extern VALUE r_gmpfrsg_const_catalan();
242
+ #endif /* MPFR */
243
+
210
244
  // _unsorted_
211
245
  extern VALUE r_gmpf_sgn(VALUE self);
212
246
  extern VALUE r_gmpf_get_prec(VALUE self);
@@ -226,6 +260,11 @@ extern VALUE r_gmprandstate_seed(VALUE self, VALUE arg);
226
260
  extern VALUE r_gmprandstate_urandomb(VALUE self, VALUE arg);
227
261
  extern VALUE r_gmprandstate_urandomm(VALUE self, VALUE arg);
228
262
 
263
+ #ifdef MPFR
264
+ // Float Random Numbers
265
+ extern VALUE r_gmprandstate_mpfr_urandomb(int argc, VALUE *argv, VALUE self);
266
+ #endif /* MPFR */
267
+
229
268
 
230
269
  /* from gmpbench_timing.c */
231
270
 
data/manual.pdf CHANGED
Binary file
data/manual.tex CHANGED
@@ -28,8 +28,8 @@
28
28
  \huge{gmp} &\\
29
29
  \midrule[3pt]
30
30
  \multicolumn{2}{r}{\large{Ruby bindings to the GMP library}}\\
31
- \multicolumn{2}{r}{\large{Edition 0.4.1}}\\
32
- \multicolumn{2}{r}{\large{1 March 2010}}
31
+ \multicolumn{2}{r}{\large{Edition 0.4.3}}\\
32
+ \multicolumn{2}{r}{\large{8 March 2010}}
33
33
  \end{tabular}
34
34
 
35
35
  \vfill
@@ -41,7 +41,7 @@
41
41
  This manual describes how to use the gmp Ruby gem, which provides bindings to
42
42
  the GNU multiple precision arithmetic library, version 4.3.x or 5.0.x.\\
43
43
  \\
44
- Copyright 2009 Sam Rawlins.\\
44
+ Copyright 2009, 2010 Sam Rawlins.\\
45
45
  No license yet.
46
46
  \newpage
47
47
 
@@ -201,7 +201,29 @@ The gmp gem includes the namespace \texttt{GMP} and four classes within \texttt{
201
201
 
202
202
  In addition to the above four classes, there is also one constant within \texttt{GMP}:
203
203
  \begin{itemize}
204
- \item \texttt{GMP::GMP\_VERSION} - The version of GMP compiled into the gmp gem.
204
+ \item \texttt{GMP::GMP\_VERSION} - The version of GMP linked into the gmp gem
205
+ \item \texttt{GMP::GMP\_CC} - The compiler that compiled GMP linked into the gmp gem
206
+ \item \texttt{GMP::GMP\_CFLAGS} - The compiler flags used to compile GMP linked into
207
+ the gmp gem
208
+ \item \texttt{GMP::GMP\_BITS\_PER\_LIMB} - The number of bits per limb
209
+ \end{itemize}
210
+
211
+ \section{MPFR basics}
212
+
213
+ The gmp gem can optionally link to MPFR, the Multiple Precision Floating-Point Reliable
214
+ Library. The x86-mswin32 version of the gmp gem comes with MPFR. This library uses the
215
+ floating-point type from GMP, and thus the MPFR functions mapped in the gmp gem become
216
+ methods in \texttt{GMP::F}.
217
+
218
+ There are additional constants within \texttt{GMP} when MPFR is linked:
219
+ \begin{itemize}
220
+ \item \texttt{GMP::MPFR\_VERSION} - The version of MPFR linked into the gmp gem.
221
+ \item \texttt{GMP::GMP\_RNDN} - Rounding mode representing "round to nearest."
222
+ \item \texttt{GMP::GMP\_RNDZ} - Rounding mode representing "round toward zero."
223
+ \item \texttt{GMP::GMP\_RNDU} - Rounding mode representing "round toward positive
224
+ infinity."
225
+ \item \texttt{GMP::GMP\_RNDD} - Rounding mode representing "round toward negative
226
+ infinity."
205
227
  \end{itemize}
206
228
 
207
229
  \newpage
@@ -693,8 +715,6 @@ There is also a convenience method available, \texttt{GMP::Z()}.\\
693
715
  }
694
716
  \end{tabular}
695
717
 
696
-
697
-
698
718
  \subsection{Integer Logic and Bit Fiddling}
699
719
 
700
720
  \begin{tabular}{p{\methwidth} l r}
@@ -742,6 +762,35 @@ There is also a convenience method available, \texttt{GMP::Z()}.\\
742
762
  }
743
763
  \end{tabular}
744
764
 
765
+ \newpage
766
+ \section{Rational Functions}
767
+
768
+ \subsection{Initializing, Assigning Rationals}
769
+
770
+ \begin{tabular}{p{\methwidth} l r}
771
+ \toprule
772
+ \textbf{new} & & GMP::Q.new $\rightarrow$ \textit{rational} \\
773
+ & & GMP::Q.new(\textit{numerator = 0}, \textit{denominator = 1}) $\rightarrow$ \textit{rational} \\
774
+ & & GMP::Q.new(\textit{str}) $\rightarrow$ \textit{rational} \\
775
+ \cmidrule(r){2-3}
776
+ & \multicolumn{2}{p{\defnwidth}}{
777
+ This method creates a new \textit{GMP::Q} rational number. It takes two optional
778
+ arguments for the value of the numerator and denominator. These arguments can each be
779
+ an instance of several classes. Here are some
780
+ examples:\newline
781
+
782
+ \texttt{GMP::Q.new \qqqquad\qqqquad \#=> 0 (default) \newline
783
+ GMP::Q.new(1) \qqqquad\qquad\ \#=> 1 (Ruby Fixnum) \newline
784
+ GMP::Q.new(1,3) \qqqquad\ \#=> 1/3 (Ruby Fixnums) \newline
785
+ GMP::Q.new("127") \qqqquad\ \#=> 127 (Ruby String)\newline
786
+ GMP::Q.new(4294967296) \qquad \#=> 4294967296 (Ruby Bignum)\newline
787
+ GMP::Q.new(GMP::Z.new(31)) \#=> 31 (GMP Integer)}
788
+ }
789
+ \end{tabular}
790
+ \newline\newline
791
+
792
+ There is also a convenience method available, \texttt{GMP::Q()}.\\
793
+
745
794
  \newpage
746
795
  \section{Random Number Functions}
747
796
 
@@ -793,12 +842,23 @@ There is also a convenience method available, \texttt{GMP::Z()}.\\
793
842
 
794
843
  \begin{tabular}{p{\methwidth} l r}
795
844
  \toprule
796
- \textbf{urandomb} & & $state$.urandomb($n$) $\rightarrow$ $n$ \\
845
+ \textbf{urandomb} & & $state$.urandomb($n$) $\rightarrow$ $integer$ \\
797
846
  \cmidrule(r){2-3}
798
847
  & \multicolumn{2}{p{\defnwidth}}{
799
848
  Generates a uniformly distributed random integer in the range $0$ to $2^n -1$,
800
849
  inclusive.
801
850
  }
802
851
  \end{tabular}
852
+ \newline\newline
853
+
854
+ \begin{tabular}{p{\methwidth} l r}
855
+ \toprule
856
+ \textbf{urandomm} & & $state$.urandomm($n$) $\rightarrow$ $integer$ \\
857
+ \cmidrule(r){2-3}
858
+ & \multicolumn{2}{p{\defnwidth}}{
859
+ Generates a uniformly distributed random integer in the range $0$ to $n -1$,
860
+ inclusive. $n$ can be an instance of \gmpz, $Fixnum$, or $Bignum$.
861
+ }
862
+ \end{tabular}
803
863
 
804
864
  \end{document}
@@ -0,0 +1,53 @@
1
+ require 'test_helper'
2
+
3
+ class MPFR_TSQRT < Test::Unit::TestCase
4
+ def setup
5
+ @rand_state = GMP::RandState.new
6
+ end
7
+
8
+ # This really should be moved to be a method of GMP::F
9
+ def integer_component(f)
10
+ index_e = f.to_s.index('e')
11
+ exp = f.to_s[(index_e+1)..-1].to_i
12
+ return 0 if exp < 0
13
+ f.to_s[2..(index_e-1)][0,exp]
14
+ end
15
+
16
+ def check_diverse(as, p, qs)
17
+ q = GMP::F(as, p)
18
+ q = q.sqrt
19
+ assert_equal(integer_component(q), qs)
20
+ end
21
+
22
+ def property1(p, rounding)
23
+ current_rounding_mode = GMP::F.default_rounding_mode
24
+ GMP::F.default_rounding_mode = rounding
25
+ x = @rand_state.mpfr_urandomb(p)
26
+ y = @rand_state.mpfr_urandomb(p)
27
+ z = x**2 + y**2
28
+ z = x / z.sqrt
29
+ assert_between(-1, 1, z, "-1 <= x/sqrt(x^2+y^2) <= 1 should hold.")
30
+ GMP::F.default_rounding_mode = GMP.const_get(current_rounding_mode)
31
+ end
32
+
33
+ def property2(p, rounding)
34
+ current_rounding_mode = GMP::F.default_rounding_mode
35
+ GMP::F.default_rounding_mode = rounding
36
+ x = @rand_state.mpfr_urandomb(p)
37
+ y = (x ** 2).sqrt
38
+ assert_true(x == y, "sqrt(x^2) = x should hold.")
39
+ GMP::F.default_rounding_mode = GMP.const_get(current_rounding_mode)
40
+ end
41
+
42
+ def test_prec
43
+ (GMP::MPFR_PREC_MIN..128).each do |p|
44
+ property1(p, GMP::GMP_RNDN)
45
+ property1(p, GMP::GMP_RNDU)
46
+ property2(p, GMP::GMP_RNDN)
47
+ end
48
+
49
+ check_diverse("635030154261163106768013773815762607450069292760790610550915652722277604820131530404842415587328",
50
+ 160,
51
+ "796887792767063979679855997149887366668464780637")
52
+ end
53
+ end
@@ -2,47 +2,112 @@ require 'test_helper'
2
2
 
3
3
  class TC_precision < Test::Unit::TestCase
4
4
  def setup
5
+ begin
6
+ GMP::MPFR_VERSION
7
+ @initial_default_prec = GMP::F.default_prec
8
+ rescue
9
+ @initial_default_prec = GMP::F.default_prec
10
+ end
11
+ end
12
+
13
+ def test_initial_default_precision
14
+ begin
15
+ GMP::MPFR_VERSION
16
+ assert_equal(53, GMP::F.default_prec, "The initial default precision with MPFR should be 53.")
17
+ rescue
18
+ assert_equal(64, GMP::F.default_prec, "The initial default precision without MPFR should be 64.")
19
+ end
20
+ end
21
+
22
+ def test_initial_default_precision2
5
23
  @pi = GMP::F.new(3.14)
6
24
  @seven_halves = GMP::F.new(GMP::Q.new(7,2), 1000)
25
+ assert_in_delta(0, GMP::F.new(), 1e-12)
26
+ assert_equal(@initial_default_prec, GMP::F.new().prec)
27
+ assert_in_delta(3.14000000000000012434, @pi, 1e-12)
28
+ assert_equal(@initial_default_prec, @pi.prec)
29
+ assert_in_delta(1, GMP::F.new(1), 1e-12)
30
+ assert_equal(@initial_default_prec, GMP::F.new(1).prec)
31
+ assert_in_delta(3.14, GMP::F.new("3.14"), 1e-12)
32
+ assert_equal(@initial_default_prec, GMP::F.new("3.14").prec)
33
+ assert_in_delta(4294967296, GMP::F.new(2**32), 1e-12)
34
+ assert_equal(@initial_default_prec, GMP::F.new(2**32).prec)
35
+ assert_in_delta(3, GMP::F.new(GMP::Z.new(3)), 1e-12)
36
+ assert_equal(@initial_default_prec, GMP::F.new(GMP::Z.new(3)).prec)
37
+ assert_in_delta(3.5, GMP::F.new(GMP::Q.new(7,2)), 1e-12)
38
+ assert_equal(@initial_default_prec, GMP::F.new(GMP::Q.new(7,2)).prec)
39
+ assert_in_delta(3.14000000000000012434, GMP::F.new(@pi), 1e-12)
40
+ assert_equal(@initial_default_prec, GMP::F.new(@pi).prec)
7
41
  end
8
42
 
9
43
  def test_default_precision
10
- assert_equal("0.e+0", GMP::F.new().to_s)
11
- assert_equal(64, GMP::F.new().prec)
12
- assert_equal("0.314000000000000012434e+1", @pi.to_s)
13
- assert_equal(64, @pi.prec)
14
- assert_equal("0.1e+1", GMP::F.new(1).to_s)
15
- assert_equal(64, GMP::F.new(1).prec)
16
- assert_equal("0.314e+1", GMP::F.new("3.14").to_s)
17
- assert_equal(64, GMP::F.new("3.14").prec)
18
- assert_equal("0.4294967296e+10", GMP::F.new(2**32).to_s)
19
- assert_equal(64, GMP::F.new(2**32).prec)
20
- assert_equal("0.3e+1", GMP::F.new(GMP::Z.new(3)).to_s)
21
- assert_equal(64, GMP::F.new(GMP::Z.new(3)).prec)
22
- assert_equal("0.35e+1", GMP::F.new(GMP::Q.new(7,2)).to_s)
23
- assert_equal(64, GMP::F.new(GMP::Q.new(7,2)).prec)
24
- assert_equal("0.314000000000000012434e+1", GMP::F.new(@pi).to_s)
25
- assert_equal(64, GMP::F.new(@pi).prec)
44
+ GMP::F.default_prec = 128
45
+ @pi = GMP::F.new(3.14)
46
+ @seven_halves = GMP::F.new(GMP::Q.new(7,2), 1000)
47
+ assert_in_delta(0, GMP::F.new(), 1e-12)
48
+ assert_equal(128, GMP::F.new().prec)
49
+ assert_in_delta(3.14000000000000012434, @pi, 1e-12)
50
+ assert_equal(128, @pi.prec)
51
+ assert_in_delta(1, GMP::F.new(1), 1e-12)
52
+ assert_equal(128, GMP::F.new(1).prec)
53
+ assert_in_delta(3.14, GMP::F.new("3.14"), 1e-12)
54
+ assert_equal(128, GMP::F.new("3.14").prec)
55
+ assert_in_delta(4294967296, GMP::F.new(2**32), 1e-12)
56
+ assert_equal(128, GMP::F.new(2**32).prec)
57
+ assert_in_delta(3, GMP::F.new(GMP::Z.new(3)), 1e-12)
58
+ assert_equal(128, GMP::F.new(GMP::Z.new(3)).prec)
59
+ assert_in_delta(3.5, GMP::F.new(GMP::Q.new(7,2)), 1e-12)
60
+ assert_equal(128, GMP::F.new(GMP::Q.new(7,2)).prec)
61
+ assert_in_delta(3.14000000000000012434, GMP::F.new(@pi), 1e-12)
62
+ assert_equal(128, GMP::F.new(@pi).prec)
63
+ GMP::F.default_prec = @initial_default_prec
26
64
  end
27
65
 
28
66
  def test_specific_precision
29
- assert_equal("0.3140000000000000124344978758017532527446746826171875e+1", GMP::F.new(3.14, 1000).to_s)
30
- assert_equal(1024, GMP::F.new(3.14, 1000).prec)
31
- assert_equal("0.1e+1", GMP::F.new(1, 1000).to_s)
32
- assert_equal(1024, GMP::F.new(1, 1000).prec)
33
- assert_equal("0.314e+1", GMP::F.new("3.14", 1000).to_s)
34
- assert_equal(1024, GMP::F.new("3.14", 1000).prec)
35
- assert_equal("0.4294967296e+10", GMP::F.new(2**32, 1000).to_s)
36
- assert_equal(1024, GMP::F.new(2**32, 1000).prec)
37
- assert_equal("0.3e+1", GMP::F.new(GMP::Z.new(3), 1000).to_s)
38
- assert_equal(1024, GMP::F.new(GMP::Z.new(3), 1000).prec)
39
- assert_equal("0.35e+1", @seven_halves.to_s)
40
- assert_equal(1024, @seven_halves.prec)
41
- assert_equal("0.35e+1", GMP::F.new(@seven_halves).to_s)
42
- assert_equal(1024, GMP::F.new(@seven_halves).prec)
43
- assert_equal("0.3140000000000000124344978758017532527446746826171875e+1", GMP::F.new(@pi, 1000).to_s)
44
- assert_equal(1024, GMP::F.new(@pi, 1000).prec)
45
- assert_equal("0.35e+1", GMP::F.new(@seven_halves, 0).to_s)
46
- assert_equal(64, GMP::F.new(@seven_halves, 0).prec)
67
+ @pi = GMP::F.new(3.14)
68
+ @seven_halves = GMP::F.new(GMP::Q.new(7,2), 1024)
69
+ assert_equal(0, GMP::F.new(3.14, 1024).to_s =~ /0\.31400000000000001243449787580175325274467468261718750*e\+1/)
70
+ assert_equal(1024, GMP::F.new(3.14, 1024).prec)
71
+ assert_in_delta(1, GMP::F.new(1, 1024), 1e-12)
72
+ assert_equal(1024, GMP::F.new(1, 1024).prec)
73
+ assert_in_delta(3.14, GMP::F.new("3.14", 1024), 1e-12)
74
+ assert_equal(1024, GMP::F.new("3.14", 1024).prec)
75
+ assert_in_delta(4294967296, GMP::F.new(2**32, 1024), 1e-12)
76
+ assert_equal(1024, GMP::F.new(2**32, 1024).prec)
77
+ assert_in_delta(3, GMP::F.new(GMP::Z.new(3), 1024), 1e-12)
78
+ assert_equal(1024, GMP::F.new(GMP::Z.new(3), 1024).prec)
79
+ assert_in_delta(3.5, @seven_halves, 1e-12)
80
+ assert_equal(1024, @seven_halves.prec)
81
+ assert_in_delta(3.5, GMP::F.new(@seven_halves), 1e-12)
82
+ assert_equal(1024, GMP::F.new(@seven_halves).prec)
83
+ assert_equal(0, GMP::F.new(@pi, 1024).to_s =~ /0\.31400000000000001243449787580175325274467468261718750*e\+1/)
84
+ assert_equal(1024, GMP::F.new(@pi, 1024).prec)
85
+ assert_in_delta(3.5, GMP::F.new(@seven_halves, 0), 1e-12)
86
+ assert_equal(@initial_default_prec, GMP::F.new(@seven_halves, 0).prec)
87
+ end
88
+
89
+ def test_set_default_prec
90
+ begin
91
+ GMP::MPFR_VERSION
92
+ GMP::F.default_prec = 100
93
+ assert_equal(100, GMP::F.default_prec, "GMP::F.default_prec should be assignable.")
94
+ GMP::F.default_prec = 130
95
+ assert_equal(130, GMP::F.default_prec, "GMP::F.default_prec should be assignable.")
96
+ GMP::F.default_prec = 1000
97
+ assert_equal(1000, GMP::F.default_prec, "GMP::F.default_prec should be assignable.")
98
+ assert_raise(RangeError) { GMP::F.default_prec = -64 }
99
+ assert_raise(TypeError) { GMP::F.default_prec = "Cow" }
100
+ rescue NameError => err
101
+ raise unless err.to_s == "uninitialized constant GMP::MPFR_VERSION"
102
+ GMP::F.default_prec = 100
103
+ assert_equal(128, GMP::F.default_prec, "GMP::F.default_prec should be assignable.")
104
+ GMP::F.default_prec = 130
105
+ assert_equal(160, GMP::F.default_prec, "GMP::F.default_prec should be assignable.")
106
+ GMP::F.default_prec = 1000
107
+ assert_equal(1024, GMP::F.default_prec, "GMP::F.default_prec should be assignable.")
108
+ assert_raise(RangeError) { GMP::F.default_prec = -64 }
109
+ assert_raise(TypeError) { GMP::F.default_prec = "Cow" }
110
+ end
111
+ GMP::F.default_prec = @initial_default_prec
47
112
  end
48
113
  end
@@ -0,0 +1,45 @@
1
+ require 'test_helper'
2
+
3
+ class TC_MPFR_Functions < Test::Unit::TestCase
4
+ def setup
5
+ @a = GMP::F(1)
6
+ end
7
+
8
+ def test_const_existence
9
+ assert_nothing_raised("GMP::F#const_log2 should be callable.") { GMP::F.const_log2 }
10
+ assert_nothing_raised("GMP::F#const_pi should be callable.") { GMP::F.const_pi }
11
+ assert_nothing_raised("GMP::F#const_euler should be callable.") { GMP::F.const_euler }
12
+ assert_nothing_raised("GMP::F#const_catalan should be callable.") { GMP::F.const_catalan }
13
+ end
14
+
15
+ def test_function_existence
16
+ assert_nothing_raised("GMP::F.sqrt should be callable.") { @a.sqrt }
17
+
18
+ assert_nothing_raised("GMP::F.log should be callable.") { @a.log }
19
+ assert_nothing_raised("GMP::F.log2 should be callable.") { @a.log2 }
20
+ assert_nothing_raised("GMP::F.log10 should be callable.") { @a.log10 }
21
+ assert_nothing_raised("GMP::F.exp should be callable.") { @a.exp }
22
+
23
+ assert_nothing_raised("GMP::F.cos should be callable.") { @a.cos }
24
+ assert_nothing_raised("GMP::F.sin should be callable.") { @a.sin }
25
+ assert_nothing_raised("GMP::F.tan should be callable.") { @a.tan }
26
+ assert_nothing_raised("GMP::F.sec should be callable.") { @a.sec }
27
+ assert_nothing_raised("GMP::F.csc should be callable.") { @a.csc }
28
+ assert_nothing_raised("GMP::F.cot should be callable.") { @a.cot }
29
+
30
+ assert_nothing_raised("GMP::F.acos should be callable.") { @a.acos }
31
+ assert_nothing_raised("GMP::F.asin should be callable.") { @a.asin }
32
+ assert_nothing_raised("GMP::F.atan should be callable.") { @a.atan }
33
+
34
+ assert_nothing_raised("GMP::F.cosh should be callable.") { @a.cosh }
35
+ assert_nothing_raised("GMP::F.sinh should be callable.") { @a.sinh }
36
+ assert_nothing_raised("GMP::F.tanh should be callable.") { @a.tanh }
37
+
38
+ assert_nothing_raised("GMP::F.acosh should be callable.") { @a.acosh }
39
+ assert_nothing_raised("GMP::F.asinh should be callable.") { @a.asinh }
40
+ assert_nothing_raised("GMP::F.atanh should be callable.") { @a.atanh }
41
+
42
+ assert_nothing_raised("GMP::F.log1p should be callable.") { @a.log1p }
43
+ assert_nothing_raised("GMP::F.expm1 should be callable.") { @a.expm1 }
44
+ end
45
+ end
@@ -0,0 +1,49 @@
1
+ require 'test_helper'
2
+
3
+ class TC_MPFR_Random < Test::Unit::TestCase
4
+ def setup
5
+ end
6
+
7
+ def test_urandomb
8
+ @a = GMP::RandState.new
9
+ @a.seed(577)
10
+ g1 = [
11
+ GMP::F("0.39810885576093713"), GMP::F("0.97212443610368071"), GMP::F("0.23084385480845748"),
12
+ GMP::F("0.29428636987062717"), GMP::F("0.76895428585342840"), GMP::F("0.69329332764704654"),
13
+ GMP::F("0.60252711974045448"), GMP::F("0.03530920538566051"), GMP::F("0.60242124958975374"),
14
+ ]
15
+ g1.size.times do |i|
16
+ assert_in_delta(g1[i], @a.mpfr_urandomb, 1e-12, "GMP::RandState should mpfr_urandomb predictably.")
17
+ end
18
+ end
19
+
20
+ def test_reseed
21
+ @c = GMP::RandState.new
22
+ @c.seed(1000)
23
+ assert_in_delta(GMP::F("0.78522728792921048"), @c.mpfr_urandomb, 1e-12, "GMP::RandState should re-seed correctly.")
24
+ assert_in_delta(GMP::F("0.94422653925308231"), @c.mpfr_urandomb, 1e-12, "GMP::RandState should re-seed correctly.")
25
+ assert_in_delta(GMP::F("0.60678541956109799"), @c.mpfr_urandomb, 1e-12, "GMP::RandState should re-seed correctly.")
26
+ @c.seed(1000)
27
+ assert_in_delta(GMP::F("0.78522728792921048"), @c.mpfr_urandomb, 1e-12, "GMP::RandState should re-seed correctly.")
28
+ assert_in_delta(GMP::F("0.94422653925308231"), @c.mpfr_urandomb, 1e-12, "GMP::RandState should re-seed correctly.")
29
+ assert_in_delta(GMP::F("0.60678541956109799"), @c.mpfr_urandomb, 1e-12, "GMP::RandState should re-seed correctly.")
30
+ @c.seed(1000)
31
+ assert_in_delta(GMP::F("0.78522728792921048"), @c.mpfr_urandomb, 1e-12, "GMP::RandState should re-seed correctly.")
32
+ assert_in_delta(GMP::F("0.94422653925308231"), @c.mpfr_urandomb, 1e-12, "GMP::RandState should re-seed correctly.")
33
+ assert_in_delta(GMP::F("0.60678541956109799"), @c.mpfr_urandomb, 1e-12, "GMP::RandState should re-seed correctly.")
34
+ end
35
+
36
+ def test_random_independent_states
37
+ @d = GMP::RandState.new
38
+ @d.seed(577)
39
+ @e = GMP::RandState.new
40
+ @e.seed(577)
41
+
42
+ assert_in_delta(GMP::F("0.39810885576093713"), @d.mpfr_urandomb, 1e-12, "GMP::RandState should be independent correctly.")
43
+ assert_in_delta(GMP::F("0.97212443610368071"), @d.mpfr_urandomb, 1e-12, "GMP::RandState should be independent correctly.")
44
+ assert_in_delta(GMP::F("0.39810885576093713"), @e.mpfr_urandomb, 1e-12, "GMP::RandState should be independent correctly.")
45
+ assert_in_delta(GMP::F("0.97212443610368071"), @e.mpfr_urandomb, 1e-12, "GMP::RandState should be independent correctly.")
46
+ assert_in_delta(GMP::F("0.23084385480845748"), @d.mpfr_urandomb, 1e-12, "GMP::RandState should be independent correctly.")
47
+ assert_in_delta(GMP::F("0.23084385480845748"), @e.mpfr_urandomb, 1e-12, "GMP::RandState should be independent correctly.")
48
+ end
49
+ end
@@ -1,4 +1,5 @@
1
1
  require 'test/unit'
2
+ require 'test_unit/assertions' # Monkey patch
2
3
  require 'rbconfig'
3
4
 
4
5
  ENV['PATH'] = [File.expand_path(
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  require 'test_helper'
4
+
4
5
  require 'tc_z'
5
6
  require 'tc_z_basic'
6
7
  require 'tc_z_logic'
@@ -23,17 +24,11 @@ require 'tc_z_jac_leg_rem'
23
24
  require 'tc_z_gcd_lcm_invert'
24
25
  require 'tc_random'
25
26
 
26
- class TC_default_prec < Test::Unit::TestCase
27
- def test_default_prec
28
- assert_equal( 64, GMP::F.default_prec, "GMP::F.default_prec should be 64.")
29
- GMP::F.default_prec = 100
30
- assert_equal(128, GMP::F.default_prec, "GMP::F.default_prec should be assignable.")
31
- GMP::F.default_prec = 130
32
- assert_equal(160, GMP::F.default_prec, "GMP::F.default_prec should be assignable.")
33
- GMP::F.default_prec = 1000
34
- assert_equal(1024, GMP::F.default_prec, "GMP::F.default_prec should be assignable.")
35
- assert_raise(RangeError) { GMP::F.default_prec = -64 }
36
- assert_raise(TypeError) { GMP::F.default_prec = "Cow" }
37
- GMP::F.default_prec = 64
38
- end
39
- end
27
+ begin
28
+ GMP::MPFR_VERSION
29
+ require 'tc_mpfr_random'
30
+ require 'tc_mpfr_functions'
31
+ require 'mpfr_tsqrt'
32
+ rescue
33
+
34
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gmp
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.1
4
+ version: 0.4.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tomasz Wegrzanowski
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2010-03-01 00:00:00 -07:00
13
+ date: 2010-03-08 00:00:00 -07:00
14
14
  default_executable:
15
15
  dependencies: []
16
16
 
@@ -37,6 +37,7 @@ files:
37
37
  - ext/ruby_gmp.h
38
38
  - ext/takeover.h
39
39
  - ext/extconf.rb
40
+ - test/mpfr_tsqrt.rb
40
41
  - test/tc_cmp.rb
41
42
  - test/tc_division.rb
42
43
  - test/tc_fib_fac_nextprime.rb
@@ -44,6 +45,8 @@ files:
44
45
  - test/tc_f_arithmetics_coersion.rb
45
46
  - test/tc_f_precision.rb
46
47
  - test/tc_logical_roots.rb
48
+ - test/tc_mpfr_functions.rb
49
+ - test/tc_mpfr_random.rb
47
50
  - test/tc_q.rb
48
51
  - test/tc_q_basic.rb
49
52
  - test/tc_random.rb
@@ -90,7 +93,7 @@ post_install_message:
90
93
  rdoc_options: []
91
94
 
92
95
  require_paths:
93
- - ext
96
+ - lib
94
97
  required_ruby_version: !ruby/object:Gem::Requirement
95
98
  requirements:
96
99
  - - ">="