gmp 0.6.43 → 0.6.47

Sign up to get free protection for your applications and to get access to all the features.
data/ext/gmpq.c CHANGED
@@ -82,11 +82,11 @@ VALUE r_gmpqsg_new(int argc, VALUE *argv, VALUE klass)
82
82
  (void)klass;
83
83
 
84
84
  if (argc > 2)
85
- rb_raise(rb_eArgError, "wrong # of arguments(%d for 0, 1 or 2)", argc);
85
+ rb_raise (rb_eArgError, "wrong # of arguments (%d for 0, 1 or 2)", argc);
86
86
 
87
87
  mpq_make_struct (res, res_val);
88
88
  mpq_init (res_val);
89
- rb_obj_call_init(res, argc, argv);
89
+ rb_obj_call_init (res, argc, argv);
90
90
 
91
91
  return res;
92
92
  }
@@ -116,17 +116,17 @@ VALUE r_gmpq_initialize(int argc, VALUE *argv, VALUE self)
116
116
  MP_RAT *self_val, *arg_val;
117
117
 
118
118
  if (argc != 0) {
119
- mpq_get_struct(self, self_val);
120
- if (argc == 1 && GMPQ_P(argv[0])) {
121
- mpq_get_struct(argv[0], arg_val);
119
+ mpq_get_struct (self, self_val);
120
+ if (argc == 1 && GMPQ_P (argv[0])) {
121
+ mpq_get_struct (argv[0], arg_val);
122
122
  mpq_set (self_val, arg_val);
123
- } else if (argc == 1 && STRING_P(argv[0])) {
124
- mpq_str_set (self_val, StringValuePtr(argv[0]));
123
+ } else if (argc == 1 && STRING_P (argv[0])) {
124
+ mpq_str_set (self_val, StringValuePtr (argv[0]));
125
125
  } else {
126
- mpz_set_value (mpq_numref(self_val), argv[0], 0); // are these segfaulting?
126
+ mpz_set_value (mpq_numref (self_val), argv[0], 0); // are these segfaulting?
127
127
  if (argc == 2) {
128
- mpz_set_value (mpq_denref(self_val), argv[1], 0); // are these segfaulting?
129
- mpq_canonicalize(self_val);
128
+ mpz_set_value (mpq_denref (self_val), argv[1], 0); // are these segfaulting?
129
+ mpq_canonicalize (self_val);
130
130
  } // AND IF ARGC != 2 ?!? WHAT JUST HAPPENED?
131
131
  }
132
132
  }
@@ -142,7 +142,7 @@ VALUE r_gmpq_initialize(int argc, VALUE *argv, VALUE self)
142
142
  VALUE r_gmpmod_q(int argc, VALUE *argv, VALUE module)
143
143
  {
144
144
  (void)module;
145
- return r_gmpqsg_new(argc, argv, cGMP_Q);
145
+ return r_gmpqsg_new (argc, argv, cGMP_Q);
146
146
  }
147
147
 
148
148
  /*
@@ -151,17 +151,17 @@ VALUE r_gmpmod_q(int argc, VALUE *argv, VALUE module)
151
151
  *
152
152
  * Efficiently swaps the contents of _p_ with _q_.
153
153
  */
154
- VALUE r_gmpq_swap(VALUE self, VALUE arg)
154
+ VALUE r_gmpq_swap (VALUE self, VALUE arg)
155
155
  {
156
156
  MP_RAT *self_val, *arg_val;
157
157
 
158
- if (!GMPQ_P(arg)) {
159
- rb_raise(rb_eTypeError, "Can't swap GMP::Q with object of other class");
158
+ if (!GMPQ_P (arg)) {
159
+ rb_raise (rb_eTypeError, "Can't swap GMP::Q with object of other class");
160
160
  }
161
161
 
162
- mpq_get_struct(self, self_val);
163
- mpq_get_struct(arg, arg_val);
164
- mpq_swap(self_val,arg_val);
162
+ mpq_get_struct (self, self_val);
163
+ mpq_get_struct (arg, arg_val);
164
+ mpq_swap (self_val,arg_val);
165
165
 
166
166
  return Qnil;
167
167
  }
@@ -284,37 +284,83 @@ VALUE r_gmprandstate_rrandomb(VALUE self, VALUE arg)
284
284
  *
285
285
  * Generate a uniformly distributed random float in the interval 0 <= rop < 1.
286
286
  */
287
- VALUE r_gmprandstate_mpfr_urandomb(int argc, VALUE *argv, VALUE self)
287
+ VALUE r_gmprandstate_mpfr_urandomb(int argc, VALUE *argv, VALUE self_val)
288
288
  {
289
- MP_RANDSTATE *self_val;
290
- MP_FLOAT *res_val;
291
- VALUE res;
289
+ MP_RANDSTATE *self;
290
+ MP_FLOAT *res;
291
+ VALUE res_val;
292
292
  unsigned long prec = 0;
293
-
293
+
294
294
  if (argc > 1)
295
- rb_raise (rb_eArgError, "wrong # of arguments(%d for 0 or 1)", argc);
295
+ rb_raise (rb_eArgError, "wrong # of arguments (%d for 0 or 1)", argc);
296
+
297
+ mprandstate_get_struct (self_val, self);
296
298
 
297
- mprandstate_get_struct (self,self_val);
298
-
299
299
  if (argc == 1) {
300
300
  if (FIXNUM_P (argv[0])) {
301
- if (FIX2INT (argv[0]) >= 0)
302
- prec = FIX2INT (argv[0]);
303
- else
304
- rb_raise (rb_eRangeError, "prec must be non-negative");
301
+ if (FIX2INT (argv[0]) < 2)
302
+ rb_raise (rb_eRangeError, "prec must be at least 2");
303
+
304
+ prec = FIX2INT (argv[0]);
305
305
  } else {
306
306
  rb_raise (rb_eTypeError, "prec must be a Fixnum");
307
307
  }
308
308
  }
309
-
310
- mpf_make_struct (res, res_val);
311
- if (prec == 0) { mpf_init (res_val); }
312
- else { mpf_init2 (res_val, prec); }
313
-
314
- mpfr_urandomb (res_val, self_val);
315
-
316
- return res;
309
+
310
+ mpf_make_struct (res_val, res);
311
+ if (prec == 0) { mpf_init (res); }
312
+ else { mpf_init2 (res, prec); }
313
+
314
+ mpfr_urandomb (res, self);
315
+
316
+ return res_val;
317
+ }
318
+
319
+ #if MPFR_VERSION_MAJOR > 2
320
+ /*
321
+ * call-seq:
322
+ * rand_state.mpfr_urandom()
323
+ *
324
+ * From the MPFR Manual:
325
+ *
326
+ * Generate a uniformly distributed random float. The floating-point number rop
327
+ * can be seen as if a random real number is generated according to the
328
+ * continuous uniform distribution on the interval [0, 1] and then rounded in
329
+ * the direction RNDN.
330
+ */
331
+ VALUE r_gmprandstate_mpfr_urandom(int argc, VALUE *argv, VALUE self_val)
332
+ {
333
+ MP_RANDSTATE *self;
334
+ MP_FLOAT *res;
335
+ mp_rnd_t rnd_mode;
336
+ VALUE res_val, prec_val, rnd_mode_val;
337
+ unsigned long int prec;
338
+
339
+ mprandstate_get_struct (self_val, self);
340
+
341
+ rb_scan_args (argc, argv, "02", &rnd_mode_val, &prec_val);
342
+ if (NIL_P (rnd_mode_val)) { rnd_mode = __gmp_default_rounding_mode; }
343
+ else { rnd_mode = r_get_rounding_mode(rnd_mode_val); }
344
+
345
+ if (NIL_P (prec_val)) {
346
+ prec = mpfr_get_default_prec();
347
+ } else if (FIXNUM_P (prec_val)) {
348
+ if (FIX2INT (prec_val) < 2)
349
+ rb_raise (rb_eRangeError, "prec must be at least 2");
350
+
351
+ prec = FIX2INT (prec_val);
352
+ } else {
353
+ rb_raise (rb_eTypeError, "prec must be a Fixnum");
354
+ }
355
+
356
+ mpf_make_struct (res_val, res);
357
+ mpf_init2 (res, prec);
358
+
359
+ mpfr_urandom (res, self, rnd_mode);
360
+
361
+ return res_val;
317
362
  }
363
+ #endif /* MPFR_VERSION_MAJOR > 2 */
318
364
  #endif /* MPFR */
319
365
 
320
366
 
@@ -328,17 +374,20 @@ void init_gmprandstate()
328
374
  // Random State Initialization
329
375
  rb_define_singleton_method(cGMP_RandState, "new", r_gmprandstatesg_new, -1);
330
376
  rb_define_method(cGMP_RandState, "initialize", r_gmprandstate_initialize, -1);
331
-
377
+
332
378
  // Random State Seeding
333
379
  rb_define_method(cGMP_RandState, "seed", r_gmprandstate_seed, 1);
334
-
380
+
335
381
  // Integer Random Numbers
336
382
  rb_define_method(cGMP_RandState, "urandomb", r_gmprandstate_urandomb, 1);
337
383
  rb_define_method(cGMP_RandState, "urandomm", r_gmprandstate_urandomm, 1);
338
384
  rb_define_method(cGMP_RandState, "rrandomb", r_gmprandstate_rrandomb, 1);
339
-
385
+
340
386
  #ifdef MPFR
341
387
  // Float Random Numbers
342
388
  rb_define_method(cGMP_RandState, "mpfr_urandomb", r_gmprandstate_mpfr_urandomb, -1);
389
+ #if MPFR_VERSION_MAJOR > 2
390
+ rb_define_method(cGMP_RandState, "mpfr_urandom", r_gmprandstate_mpfr_urandom, -1);
391
+ #endif /* MPFR_VERSION_MAJOR > 2 */
343
392
  #endif /* MPFR */
344
393
  }
@@ -65,9 +65,12 @@ typedef __gmp_randstate_struct MP_RANDSTATE;
65
65
  #define GMPZ_P(value) (rb_obj_is_instance_of(value, cGMP_Z) == Qtrue)
66
66
  #define GMPQ_P(value) (rb_obj_is_instance_of(value, cGMP_Q) == Qtrue)
67
67
  #define GMPF_P(value) (rb_obj_is_instance_of(value, cGMP_F) == Qtrue)
68
- #define mpz_set_bignum(var_mpz,var_bignum) { \
69
- VALUE tmp = rb_funcall (rb_funcall (var_bignum, rb_intern ("to_s"), 1, INT2FIX(32)), rb_intern("upcase"), 0); \
70
- mpz_set_str (var_mpz, StringValuePtr (tmp), 32); \
68
+ #define mpz_set_bignum(var_mpz,var_bignum) { \
69
+ VALUE tmp = rb_funcall ( \
70
+ rb_funcall (var_bignum, rb_intern ("to_s"), 1, INT2FIX (32)), \
71
+ rb_intern ("upcase"), \
72
+ 0); \
73
+ mpz_set_str (var_mpz, StringValuePtr (tmp), 32); \
71
74
  }
72
75
  /*VALUE tmp = rb_funcall (var_bignum, rb_intern ("to_s"), 1, INT2FIX(32)); \*/
73
76
  /*#define mpz_set_bignum(var_mpz,var_bignum) { \
@@ -76,10 +79,10 @@ typedef __gmp_randstate_struct MP_RANDSTATE;
76
79
  }*/
77
80
  #define mpz_temp_alloc(var) { var=malloc(sizeof(MP_INT)); }
78
81
  #define mpz_temp_init(var) { mpz_temp_alloc(var); mpz_init(var); }
79
- #define mpz_temp_from_bignum(var,var_bignum) { \
80
- VALUE tmp = rb_funcall (var_bignum, rb_intern ("to_s"), 1, INT2FIX(32)); \
81
- mpz_temp_alloc(var); \
82
- mpz_init_set_str (var, StringValuePtr (tmp), 32); \
82
+ #define mpz_temp_from_bignum(var,var_bignum) { \
83
+ VALUE tmp = rb_funcall (var_bignum, rb_intern ("to_s"), 1, INT2FIX (32)); \
84
+ mpz_temp_alloc(var); \
85
+ mpz_init_set_str (var, StringValuePtr (tmp), 32); \
83
86
  }
84
87
  #define mpz_temp_free(var) { mpz_clear(var); free(var); }
85
88
  #define mpf_temp_alloc(var) { var=malloc(sizeof(MP_FLOAT)); }
@@ -90,20 +93,32 @@ typedef __gmp_randstate_struct MP_RANDSTATE;
90
93
  #endif
91
94
 
92
95
  #if defined(MPFR) && defined(HAVE_MPFR_H)
93
- #define mpf_get_struct_prec(ruby_var,c_var,prec) { mpf_get_struct(ruby_var,c_var); prec = mpfr_get_prec(c_var); }
94
- #define mpf_make_struct_init(ruby_var,c_var,prec) { mpf_make_struct(ruby_var,c_var); mpfr_init2 (c_var,prec); }
96
+ #define mpf_get_struct_prec(ruby_var,c_var,prec) { \
97
+ mpf_get_struct (ruby_var,c_var); \
98
+ prec = mpfr_get_prec (c_var); \
99
+ }
100
+ #define mpf_make_struct_init(ruby_var,c_var,prec) { \
101
+ mpf_make_struct (ruby_var,c_var); \
102
+ mpfr_init2 (c_var,prec); \
103
+ }
95
104
  #define mpf_temp_init(var,prec) { mpf_temp_alloc(var); mpfr_init2(var,prec); }
96
105
  #define mpf_temp_free(var) { mpfr_clear(var); free(var); }
97
106
  #define r_mpf_init(var1) (mpfr_init(var1))
98
107
  #define r_mpf_init2(var1, var2) (mpfr_init2(var1, var2))
99
- #define r_mpf_set_z(var1, var2) (mpfr_set_z(var1, var2, __gmp_default_rounding_mode))
100
- #define r_mpf_set_q(var1, var2) (mpfr_set_q(var1, var2, __gmp_default_rounding_mode))
108
+ #define r_mpfr_set_z(var1, var2, rnd_mode) (mpfr_set_z(var1, var2, rnd_mode))
109
+ #define r_mpfr_set_q(var1, var2, rnd_mode) (mpfr_set_q(var1, var2, rnd_mode))
101
110
  #define r_mpf_set_d(var1, var2) (mpfr_set_d(var1, var2, __gmp_default_rounding_mode))
102
111
  #define r_mpf_set_str(var1, var2, var3) (mpfr_set_str(var1, var2, var3, __gmp_default_rounding_mode))
103
112
  #define r_mpf_cmp(var1, var2) (mpfr_cmp(var1, var2))
104
- #else
105
- #define mpf_get_struct_prec(ruby_var,c_var,prec) { mpf_get_struct(ruby_var,c_var); prec = mpf_get_prec(c_var); }
106
- #define mpf_make_struct_init(ruby_var,c_var,prec) { mpf_make_struct(ruby_var,c_var); mpf_init2 (c_var,prec); }
113
+ #else /* not MPFR */
114
+ #define mpf_get_struct_prec(ruby_var,c_var,prec) { \
115
+ mpf_get_struct (ruby_var,c_var); \
116
+ prec = mpf_get_prec (c_var); \
117
+ }
118
+ #define mpf_make_struct_init(ruby_var,c_var,prec) { \
119
+ mpf_make_struct (ruby_var,c_var); \
120
+ mpf_init2 (c_var,prec); \
121
+ }
107
122
  #define mpf_temp_init(var,prec) { mpf_temp_alloc(var); mpf_init2(var,prec); }
108
123
  #define mpf_temp_free(var) { mpf_clear(var); free(var); }
109
124
  #define r_mpf_init(var1) (mpf_init(var1))
@@ -113,7 +128,7 @@ typedef __gmp_randstate_struct MP_RANDSTATE;
113
128
  #define r_mpf_set_d(var1, var2) (mpf_set_d(var1, var2))
114
129
  #define r_mpf_set_str(var1, var2, var3) (mpf_set_str(var1, var2, var3))
115
130
  #define r_mpf_cmp(var1, var2) (mpf_cmp(var1, var2))
116
- #endif
131
+ #endif /* MPFR */
117
132
 
118
133
  #ifdef FIXNUM_WIDTH /* RBX check */
119
134
  #if (((8*SIZEOF_INTPTR_T) - TAG_FIXNUM_SHIFT -1) > 60) /* 64-bit */
@@ -136,6 +151,7 @@ typedef __gmp_randstate_struct MP_RANDSTATE;
136
151
  #define EXPECTED_ZX "Expected GMP::Z or Fixnum"
137
152
  #define EXPECTED_X "Expected Fixnum"
138
153
  #define EXPECTED_Z "Expected GMP::Z"
154
+ #define EXPECTED_F "Expected GMP::F"
139
155
  #define EXPECTED_FD "Expected GMP::F or Float"
140
156
  #define typeerror(expected) rb_raise(rb_eTypeError, EXPECTED_##expected)
141
157
  #define typeerror_as(expected, argname) rb_raise(rb_eTypeError, EXPECTED_##expected " as " argname)
@@ -259,7 +275,11 @@ extern VALUE r_gmpq_den(VALUE self);
259
275
  // Initializing, Assigning Floats
260
276
  extern VALUE r_gmpfsg_new(int argc, VALUE *argv, VALUE klass);
261
277
  extern VALUE r_gmpf_initialize(int argc, VALUE *argv, VALUE self);
278
+ #ifndef MPFR
262
279
  extern void mpf_set_value(MP_FLOAT *self_val, VALUE arg);
280
+ #else
281
+ extern void mpfr_set_value(MP_FLOAT *self_val, VALUE arg, mpfr_rnd_t rnd_mode_val);
282
+ #endif
263
283
  extern VALUE r_gmpmod_f(int argc, VALUE *argv, VALUE module);
264
284
  extern VALUE r_gmpf_get_prec(VALUE self);
265
285
  extern VALUE r_gmpf_set_prec(VALUE self, VALUE arg);
@@ -267,11 +287,7 @@ extern VALUE r_gmpf_set_prec_raw(VALUE self, VALUE arg);
267
287
 
268
288
  // Converting Floats
269
289
  extern VALUE r_gmpf_to_d(VALUE self);
270
- #ifdef MPFR
271
290
  extern VALUE r_gmpf_to_s(int argc, VALUE *argv, VALUE self);
272
- #else
273
- extern VALUE r_gmpf_to_s(VALUE self);
274
- #endif
275
291
 
276
292
  // Float Arithmetic
277
293
  #ifndef MPFR
data/manual.pdf CHANGED
Binary file
data/manual.tex CHANGED
@@ -34,8 +34,8 @@
34
34
  \huge{gmp} &\\
35
35
  \midrule[3pt]
36
36
  \multicolumn{2}{r}{\large{Ruby bindings to the GMP library}}\\
37
- \multicolumn{2}{r}{\large{Edition 0.6.41}}\\
38
- \multicolumn{2}{r}{\large{15 October 2013}}
37
+ \multicolumn{2}{r}{\large{Edition 0.6.47}}\\
38
+ \multicolumn{2}{r}{\large{31 December 2013}}
39
39
  \end{tabular}
40
40
 
41
41
  \vfill
@@ -48,7 +48,7 @@ This manual describes how to use the gmp Ruby gem, which provides bindings to
48
48
  the GNU multiple precision arithmetic library, version 4.3.x or 5.x.\\
49
49
  \\
50
50
  Copyright 2009, 2010, 2011, 2012, 2013 Sam Rawlins.\\
51
- No license yet.
51
+ Apache License, Version 2.0
52
52
  \newpage
53
53
 
54
54
  \tableofcontents
@@ -1206,9 +1206,106 @@ There is also a convenience method available, \texttt{GMP::Q()}.\\
1206
1206
 
1207
1207
  \subsection{Initializing, Assigning Floats}
1208
1208
 
1209
+ \begin{tabular}{p{\methwidth} l r}
1210
+ \toprule
1211
+ \textbf{new} & & GMP::F.new $\rightarrow$ \textit{float} \\
1212
+ & & GMP::F.new(\textit{numeric}, \begin{small}precision = default, rnd\_mode = GMP\_RNDN\end{small}) $\rightarrow$ \textit{float} \\
1213
+ & & GMP::F.new(\textit{str}, \begin{small}base = 0\end{small}) $\rightarrow$ \textit{float} \\
1214
+ \cmidrule(r){2-3}
1215
+ & \multicolumn{2}{p{\defnwidth}}{
1216
+ This method creates a new \gmpfs float. It typically takes one optional
1217
+ argument for the value of the float. This argument can be one of several
1218
+ classes. Optionally, a precision can be passed.\newline
1219
+
1220
+ If MPFR is available, an optional rounding mode can also be passed.
1221
+ \newline
1222
+
1223
+ If the first argument is a String, then a second argument, the base, may be
1224
+ optionally supplied. Here are some examples:\newline
1225
+
1226
+ \texttt{GMP::F.new \qqqquad\qqqquad \#=> 0 (default) \newline
1227
+ GMP::F.new(5) \qqqquad\qquad\ \#=> 5 (Ruby Fixnum) \newline
1228
+ GMP::F.new(GMP::Z.new(31)) \#=> 31 (GMP Integer)\newline
1229
+ GMP::F.new(3**41) \qqqquad\ \#=> 0.36472996377170788e+20\newline
1230
+ >\qqqquad\qqqquad\qqqquad\qquad\quad (Ruby Bignum)\newline
1231
+ GMP::F.new(3**41, 32) \qquad\ \#=> 0.36472996375+20\newline
1232
+ >\qqqquad\qqqquad\qqqquad\qquad\quad (Ruby Bignum with precision)\newline
1233
+ GMP::F.new(3**41, 32, GMP::GMP\_RNDU) \#=> 0.36472996375+20\newline
1234
+ >\qqqquad\qqqquad\ (Ruby Bignum with precision and a rounding mode)\newline
1235
+ GMP::F.new("20") \qqqquad\quad \#=> 20 (Ruby String)\newline
1236
+ GMP::F.new("0x20") \qqqquad \#=> 32 (Ruby hexadecimal-format String)\newline
1237
+ GMP::F.new("111", 16) \qquad\ \#=> 111 (Ruby String with precision)\newline
1238
+ GMP::F.new("111", 16, 2) \quad \#=> 7\newline
1239
+ >\qqqquad\qqqquad\qqqquad\quad (Ruby String with precision and a base)}
1240
+ }
1241
+ \end{tabular}
1242
+ \newline\newline
1243
+
1244
+ There is also a convenience method available, \texttt{GMP::F()}.\\
1245
+
1246
+ \begin{tabular}{p{\methwidth} l r}
1247
+ \toprule
1248
+ \textbf{nan} & (MPFR only) & GMP::F.nan $\rightarrow$ \textit{NaN} \\
1249
+ \cmidrule(r){2-3}
1250
+ & \multicolumn{2}{p{\defnwidth}}{
1251
+ Returns NaN, an instance of \gmpfs.
1252
+ }
1253
+ \end{tabular}
1254
+ \newline\newline
1255
+
1256
+ \begin{tabular}{p{\methwidth} l r}
1257
+ \toprule
1258
+ \textbf{inf} & (MPFR only) & GMP::F.inf(\textit{sign} = 1) $\rightarrow$ \textit{Inf} \\
1259
+ \cmidrule(r){2-3}
1260
+ & \multicolumn{2}{p{\defnwidth}}{
1261
+ Returns Inf (positive infinity) or -Inf (negative infinity), an instance of
1262
+ \gmpfs, based on the sign of \textit{sign}, which must be a Fixnum, and
1263
+ defaults to 1.
1264
+ }
1265
+ \end{tabular}
1266
+ \newline\newline
1267
+
1268
+ \begin{tabular}{p{\methwidth} l r}
1269
+ \toprule
1270
+ \textbf{zero} & (MPFR only) & GMP::F.zero(\textit{sign} = 1) $\rightarrow$ \textit{zero} \\
1271
+ \cmidrule(r){2-3}
1272
+ & \multicolumn{2}{p{\defnwidth}}{
1273
+ Returns zero or -zero, an instance of \gmpfs, based on the sign of
1274
+ \textit{sign}, which must be a Fixnum, and defaults to 1.
1275
+ }
1276
+ \end{tabular}
1277
+ \newline\newline
1278
+
1279
+ \subsection{Floating-point Conversion Functions}
1280
+
1281
+ Every method below accepts two additional parameters in addition to any
1282
+ required parameters. These are $rnd\_mode$, the rounding mode to use in
1283
+ calculation, which defaults to \textit{GMP::GMP\_RNDN}, and $res\_prec$, the
1284
+ precision of the result, which defaults to the \textit{f.prec}, the precision
1285
+ of $f$.\\
1286
+
1287
+ TONS OF MISSING DOCUMENTATION\\
1288
+
1289
+ \begin{tabular}{p{\methwidth} l r}
1290
+ \toprule
1291
+ \textbf{frexp} & (MPFR 3.1 only) & $f$.frexp(\begin{small}rnd\_mode = GMP\_RNDN, res\_prec=$f$.prec\end{small}) $\rightarrow$ $exp$, $g$ \\
1292
+ \cmidrule(r){2-3}
1293
+ & \multicolumn{2}{p{\defnwidth}}{
1294
+ Set $exp$ and $y$ such that $0.5 <= abs(y) < 1$ and $y$ times 2 raised to
1295
+ $exp$ equals $x$ rounded to $res\_prec$, using $rnd\_mode$. If $x$ is zero,
1296
+ then $y$ is set to a zero of the same sign and $exp$ is set to 0. If $x$ is
1297
+ NaN or an infinity, then $y$ is set to the same value and $exp$ is undefined.
1298
+ }
1299
+ \end{tabular}
1300
+ \newline\newline
1301
+
1209
1302
  \subsection{Floating-point Special Functions (MPFR Only)}
1210
1303
 
1211
- Every method below accepts two additional parameters in addition to any required parameters. These are $rnd\_mode$, the rounding mode to use in calculation, which defaults to \textit{GMP::GMP\_RNDN}, and $res\_prec$, the precision of the result, which defaults to the \textit{f.prec}, the precision of $f$.\\
1304
+ Every method below accepts two additional parameters in addition to any
1305
+ required parameters. These are $rnd\_mode$, the rounding mode to use in
1306
+ calculation, which defaults to \textit{GMP::GMP\_RNDN}, and $res\_prec$, the
1307
+ precision of the result, which defaults to the \textit{f.prec}, the precision
1308
+ of $f$.\\
1212
1309
 
1213
1310
  \begin{tabular}{p{\methwidth} l r}
1214
1311
  \toprule
@@ -1507,7 +1604,45 @@ Every method below accepts two additional parameters in addition to any required
1507
1604
  }
1508
1605
  \end{tabular}
1509
1606
 
1510
- \subsection{Floating-point Miscellaneous Functions (MPFR Only)}
1607
+ \subsection{Floating-Point Random Numbers (MPFR only)}
1608
+
1609
+ \begin{tabular}{p{\methwidth} l r}
1610
+ \toprule
1611
+ \textbf{mpfr\_urandomb} & & $state$.mpfr\_urandomb() $\rightarrow$ $floating-point$ \\
1612
+ & & $state$.mprf\_urandomb($prec$) $\rightarrow$ $floating-point$ \\
1613
+ \cmidrule(r){2-3}
1614
+ & \multicolumn{2}{p{\defnwidth}}{
1615
+ Generates a uniformly distributed random float in the between $0$ and $1$.
1616
+ More precisely, the number can be seen as a float with a random non-normalized
1617
+ significand and exponent 0, which is then normalized (thus if $e$ denotes the
1618
+ exponent after normalization, then the least $-e$ significant bits of the
1619
+ significand are always 0).
1620
+
1621
+ Optionally pass $prec$, the precision of the resultant GMP::F number.
1622
+ }
1623
+ \end{tabular}
1624
+ \newline\newline
1625
+
1626
+ \begin{tabular}{p{\methwidth} l r}
1627
+ \toprule
1628
+ \textbf{mpfr\_urandom} & & $state$.mpfr\_urandom() $\rightarrow$ $integer$ \\
1629
+ & & $state$.mprf\_urandom($rnd\_mode$) $\rightarrow$ $floating-point$ \\
1630
+ & & $state$.mprf\_urandom($rnd\_mode$, $prec$) $\rightarrow$ $floating-point$ \\
1631
+ \cmidrule(r){2-3}
1632
+ & \multicolumn{2}{p{\defnwidth}}{
1633
+ Generate a uniformly distributed random float. The floating-point number
1634
+ can be seen as if a random real number is generated according to the continuous
1635
+ uniform distribution on the interval [0, 1] and then rounded in the direction
1636
+ $rnd$.
1637
+
1638
+ Optionally pass $rnd\_mode$, a rounding mode.
1639
+
1640
+ Also optionally pass $prec$, the precision of the resultant GMP::F number.
1641
+ }
1642
+ \end{tabular}
1643
+ \newline\newline
1644
+
1645
+ \subsection{Floating-point Miscellaneous Functions (MPFR only)}
1511
1646
 
1512
1647
  \begin{tabular}{p{\methwidth} l r}
1513
1648
  \toprule