number 0.9.10 → 0.9.11
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/number/bounds.c +24 -24
- data/ext/number/complex.c +23 -11
- data/ext/number/decompose.c +10 -10
- data/ext/number/interval.c +31 -20
- data/ext/number/number.c +22 -1
- data/ext/number/number.h +4 -3
- data/ext/number/real.c +89 -45
- data/ext/number/real_bounds.c +17 -17
- metadata +2 -2
data/ext/number/bounds.c
CHANGED
@@ -29,6 +29,30 @@ void bounds_free (Bounds* bounds)
|
|
29
29
|
}
|
30
30
|
}
|
31
31
|
|
32
|
+
Bounds* bounds_new ()
|
33
|
+
{
|
34
|
+
Bounds* bounds = malloc(sizeof(Bounds));
|
35
|
+
|
36
|
+
if (bounds == NULL)
|
37
|
+
{
|
38
|
+
return NULL;
|
39
|
+
}
|
40
|
+
|
41
|
+
memset(bounds, 0, sizeof(Bounds));
|
42
|
+
|
43
|
+
mpfr_init2(bounds->re_min, PREC);
|
44
|
+
mpfr_init2(bounds->re_max, PREC);
|
45
|
+
mpfr_init2(bounds->im_min, PREC);
|
46
|
+
mpfr_init2(bounds->im_max, PREC);
|
47
|
+
|
48
|
+
mpfr_set_inf(bounds->re_min, 1);
|
49
|
+
mpfr_set_inf(bounds->re_max, -1);
|
50
|
+
mpfr_set_inf(bounds->im_min, 1);
|
51
|
+
mpfr_set_inf(bounds->im_max, -1);
|
52
|
+
|
53
|
+
return bounds;
|
54
|
+
}
|
55
|
+
|
32
56
|
void bounds_update_re (Bounds* bounds, mpfr_t num, int re_closed, int exact)
|
33
57
|
{
|
34
58
|
int min_cmp = mpfr_cmp(bounds->re_min, num);
|
@@ -84,27 +108,3 @@ void bounds_update (Bounds* bounds, mpc_t num, int re_closed, int im_closed, int
|
|
84
108
|
mpfr_clear(re);
|
85
109
|
mpfr_clear(im);
|
86
110
|
}
|
87
|
-
|
88
|
-
Bounds* bounds_new ()
|
89
|
-
{
|
90
|
-
Bounds* bounds = malloc(sizeof(Bounds));
|
91
|
-
|
92
|
-
if (bounds == NULL)
|
93
|
-
{
|
94
|
-
return NULL;
|
95
|
-
}
|
96
|
-
|
97
|
-
memset(bounds, 0, sizeof(Bounds));
|
98
|
-
|
99
|
-
mpfr_init2(bounds->re_min, PREC);
|
100
|
-
mpfr_init2(bounds->re_max, PREC);
|
101
|
-
mpfr_init2(bounds->im_min, PREC);
|
102
|
-
mpfr_init2(bounds->im_max, PREC);
|
103
|
-
|
104
|
-
mpfr_set_inf(bounds->re_min, 1);
|
105
|
-
mpfr_set_inf(bounds->re_max, -1);
|
106
|
-
mpfr_set_inf(bounds->im_min, 1);
|
107
|
-
mpfr_set_inf(bounds->im_max, -1);
|
108
|
-
|
109
|
-
return bounds;
|
110
|
-
}
|
data/ext/number/complex.c
CHANGED
@@ -150,34 +150,46 @@ void complex_free (Complex* complex)
|
|
150
150
|
}
|
151
151
|
|
152
152
|
/*
|
153
|
-
* Returns the
|
153
|
+
* Returns the size of the string representation of complex as a long.
|
154
154
|
*/
|
155
155
|
long complex_strlen (Complex* complex)
|
156
156
|
{
|
157
|
-
|
157
|
+
if (interval_zero_p(complex->im))
|
158
|
+
{
|
159
|
+
return interval_strlen(complex->re);
|
160
|
+
}
|
161
|
+
else
|
162
|
+
{
|
163
|
+
int sign = 1;
|
164
|
+
int i = 1;
|
165
|
+
int re = interval_strlen(complex->re);
|
166
|
+
int im = interval_strlen(complex->im);
|
167
|
+
|
168
|
+
return re + sign + im + i;
|
169
|
+
}
|
158
170
|
}
|
159
171
|
|
160
172
|
/*
|
161
173
|
* Puts a string representation of complex into the string pointed to by buf.
|
162
174
|
*
|
163
|
-
* complex:
|
175
|
+
* complex: [1:1 < (2:1) < 3:1]+[0:0 ≤ (0:0) ≤ 0:0]i => str: "[1:1 < (2:1) < 3:1]"
|
176
|
+
* complex: [1:1 < (2:1) < 3:1]+[1:0 ≤ (1:0) ≤ 1:0]i => str: "[1:1 < (2:1) < 3:1]+1:0i"
|
164
177
|
*/
|
165
178
|
void complex_print (char* buf, Complex* complex)
|
166
179
|
{
|
167
|
-
char rbuf[interval_strlen(complex->re)];
|
168
|
-
char ibuf[interval_strlen(complex->im)];
|
169
|
-
|
170
180
|
if (interval_zero_p(complex->im))
|
171
181
|
{
|
172
|
-
interval_print(
|
173
|
-
sprintf(buf, "%s", rbuf);
|
182
|
+
interval_print(buf, complex->re);
|
174
183
|
}
|
175
184
|
else
|
176
185
|
{
|
177
|
-
|
178
|
-
|
186
|
+
char re_buf[interval_strlen(complex->re)];
|
187
|
+
char im_buf[interval_strlen(complex->im)];
|
188
|
+
|
189
|
+
interval_print(re_buf, complex->re);
|
190
|
+
interval_print(im_buf, complex->im);
|
179
191
|
|
180
|
-
sprintf(buf, "%s+%si",
|
192
|
+
sprintf(buf, "%s+%si", re_buf, im_buf);
|
181
193
|
}
|
182
194
|
}
|
183
195
|
|
data/ext/number/decompose.c
CHANGED
@@ -162,40 +162,40 @@ Complex* complex_re_width (Complex* complex)
|
|
162
162
|
|
163
163
|
Complex* complex_ll (Complex* complex)
|
164
164
|
{
|
165
|
-
Interval* re = interval_from_real(complex->re->l);
|
166
|
-
Interval* im = interval_from_real(complex->im->l);
|
165
|
+
Interval* re = interval_from_real(real_dup(complex->re->l));
|
166
|
+
Interval* im = interval_from_real(real_dup(complex->im->l));
|
167
167
|
|
168
168
|
return complex_new(re, im);
|
169
169
|
}
|
170
170
|
|
171
171
|
Complex* complex_lu (Complex* complex)
|
172
172
|
{
|
173
|
-
Interval* re = interval_from_real(complex->re->l);
|
174
|
-
Interval* im = interval_from_real(complex->im->u);
|
173
|
+
Interval* re = interval_from_real(real_dup(complex->re->l));
|
174
|
+
Interval* im = interval_from_real(real_dup(complex->im->u));
|
175
175
|
|
176
176
|
return complex_new(re, im);
|
177
177
|
}
|
178
178
|
|
179
179
|
Complex* complex_n (Complex* complex)
|
180
180
|
{
|
181
|
-
Interval* re = interval_from_real(complex->re->n);
|
182
|
-
Interval* im = interval_from_real(complex->im->n);
|
181
|
+
Interval* re = interval_from_real(real_dup(complex->re->n));
|
182
|
+
Interval* im = interval_from_real(real_dup(complex->im->n));
|
183
183
|
|
184
184
|
return complex_new(re, im);
|
185
185
|
}
|
186
186
|
|
187
187
|
Complex* complex_ul (Complex* complex)
|
188
188
|
{
|
189
|
-
Interval* re = interval_from_real(complex->re->u);
|
190
|
-
Interval* im = interval_from_real(complex->im->l);
|
189
|
+
Interval* re = interval_from_real(real_dup(complex->re->u));
|
190
|
+
Interval* im = interval_from_real(real_dup(complex->im->l));
|
191
191
|
|
192
192
|
return complex_new(re, im);
|
193
193
|
}
|
194
194
|
|
195
195
|
Complex* complex_uu (Complex* complex)
|
196
196
|
{
|
197
|
-
Interval* re = interval_from_real(complex->re->u);
|
198
|
-
Interval* im = interval_from_real(complex->im->u);
|
197
|
+
Interval* re = interval_from_real(real_dup(complex->re->u));
|
198
|
+
Interval* im = interval_from_real(real_dup(complex->im->u));
|
199
199
|
|
200
200
|
return complex_new(re, im);
|
201
201
|
}
|
data/ext/number/interval.c
CHANGED
@@ -28,37 +28,53 @@ void interval_free (Interval* interval)
|
|
28
28
|
}
|
29
29
|
|
30
30
|
/*
|
31
|
-
* Returns the
|
31
|
+
* Returns the size of the string representation of interval as a long.
|
32
32
|
*/
|
33
33
|
long interval_strlen (Interval* interval)
|
34
34
|
{
|
35
|
-
|
35
|
+
if (interval_degenerate_p(interval))
|
36
|
+
{
|
37
|
+
return real_strlen(interval->n);
|
38
|
+
}
|
39
|
+
else
|
40
|
+
{
|
41
|
+
int cmp = 1;
|
42
|
+
int space = 1;
|
43
|
+
int bracket = 1;
|
44
|
+
int l = real_strlen(interval->l);
|
45
|
+
int n = real_strlen(interval->n);
|
46
|
+
int u = real_strlen(interval->u);
|
47
|
+
|
48
|
+
return bracket + l + space + cmp + space + bracket + n + bracket + space + cmp + space + u + bracket;
|
49
|
+
}
|
36
50
|
}
|
37
51
|
|
38
52
|
/*
|
39
53
|
* Puts a string representation of interval into the string pointed to by buf.
|
40
54
|
*
|
41
|
-
* interval:
|
42
|
-
* interval:
|
55
|
+
* interval: [1:1 < (2:1) < 3:1] => str: "[1:1 < (2:1) < 3:1]"
|
56
|
+
* interval: [0:0 ≤ (0:0) ≤ 0:0] => str: "0:0"
|
43
57
|
*/
|
44
58
|
void interval_print(char* buf, Interval* interval)
|
45
59
|
{
|
46
|
-
char n_str[real_strlen(interval->n)];
|
47
|
-
char l_str[real_strlen(interval->l)];
|
48
|
-
char u_str[real_strlen(interval->u)];
|
49
|
-
|
50
60
|
if (interval_degenerate_p(interval))
|
51
61
|
{
|
52
|
-
real_print(
|
53
|
-
sprintf(buf, "%s", n_str);
|
62
|
+
real_print(buf, interval->n);
|
54
63
|
}
|
55
64
|
else
|
56
65
|
{
|
57
|
-
|
58
|
-
|
59
|
-
|
66
|
+
char* L = (interval->L) ? "≤" : "<";
|
67
|
+
char* R = (interval->R) ? "≤" : "<";
|
68
|
+
|
69
|
+
char l[real_strlen(interval->l)];
|
70
|
+
char n[real_strlen(interval->n)];
|
71
|
+
char u[real_strlen(interval->u)];
|
60
72
|
|
61
|
-
|
73
|
+
real_print(l, interval->l);
|
74
|
+
real_print(n, interval->n);
|
75
|
+
real_print(u, interval->u);
|
76
|
+
|
77
|
+
sprintf(buf, "[%s %s (%s) %s %s]", l, L, n, R, u);
|
62
78
|
}
|
63
79
|
}
|
64
80
|
|
@@ -75,12 +91,7 @@ int interval_span_p (Interval* interval, Real* real)
|
|
75
91
|
*/
|
76
92
|
int interval_span_zero_p (Interval* interval)
|
77
93
|
{
|
78
|
-
|
79
|
-
int result = interval_span_p(interval, zero);
|
80
|
-
|
81
|
-
real_free(zero);
|
82
|
-
|
83
|
-
return result;
|
94
|
+
return (interval->L && ZERO(interval->l)) || (interval->R && ZERO(interval->u)) || (NEG(interval->l) && POS(interval->u));
|
84
95
|
}
|
85
96
|
|
86
97
|
/*
|
data/ext/number/number.c
CHANGED
@@ -44,7 +44,6 @@ VALUE rb_String_to_number (VALUE str)
|
|
44
44
|
Real* real = real_from_str((char*)RSTRING_PTR(RARRAY_PTR(real_captures)[0]), NUM2LONG(integer));
|
45
45
|
|
46
46
|
DATA_PTR(result) = complex_from_real(real);
|
47
|
-
real_free(real);
|
48
47
|
|
49
48
|
return result;
|
50
49
|
}
|
@@ -291,6 +290,11 @@ VALUE rb_Number_initialize_copy (VALUE number, VALUE copy)
|
|
291
290
|
return Qnil; /* not reached */
|
292
291
|
}
|
293
292
|
|
293
|
+
VALUE rb_Number_to_c (VALUE number)
|
294
|
+
{
|
295
|
+
/* TODO */
|
296
|
+
}
|
297
|
+
|
294
298
|
VALUE rb_Number_to_f (VALUE number)
|
295
299
|
{
|
296
300
|
if (complex_re_normal_p(DATA_PTR(number)))
|
@@ -323,6 +327,22 @@ VALUE rb_Number_to_i (VALUE number)
|
|
323
327
|
}
|
324
328
|
}
|
325
329
|
|
330
|
+
VALUE rb_Number_to_int (VALUE number)
|
331
|
+
{
|
332
|
+
if (complex_re_normal_p(DATA_PTR(number)))
|
333
|
+
{
|
334
|
+
char buf[10000];
|
335
|
+
|
336
|
+
complex_print_int(buf, DATA_PTR(number));
|
337
|
+
|
338
|
+
return rb_cstr_to_inum(buf, 10, false);
|
339
|
+
}
|
340
|
+
else
|
341
|
+
{
|
342
|
+
return INT2FIX(0);
|
343
|
+
}
|
344
|
+
}
|
345
|
+
|
326
346
|
VALUE rb_Number_to_s (VALUE number)
|
327
347
|
{
|
328
348
|
char buf[1000];
|
@@ -1456,6 +1476,7 @@ void Init_number ()
|
|
1456
1476
|
|
1457
1477
|
rb_define_method(rb_cNumber, "to_f", rb_Number_to_f, 0);
|
1458
1478
|
rb_define_method(rb_cNumber, "to_i", rb_Number_to_i, 0);
|
1479
|
+
rb_define_method(rb_cNumber, "to_int", rb_Number_to_int, 0);
|
1459
1480
|
rb_define_method(rb_cNumber, "to_s", rb_Number_to_s, 0);
|
1460
1481
|
rb_define_method(rb_cNumber, "to_number", rb_Number_dummy, 0);
|
1461
1482
|
rb_define_method(rb_cNumber, "coerce", rb_Number_coerce, 1);
|
data/ext/number/number.h
CHANGED
@@ -25,14 +25,15 @@
|
|
25
25
|
#define true 1
|
26
26
|
#define false 0
|
27
27
|
|
28
|
-
#define
|
28
|
+
#define NAN_FLAG 1
|
29
29
|
#define POS_INF_FLAG 2
|
30
30
|
#define NEG_INF_FLAG 3
|
31
|
+
#define REAL_FLAG 4
|
31
32
|
|
32
|
-
#define
|
33
|
-
#define NaN(real) ((real)->flag == NaN_FLAG)
|
33
|
+
#define NaN(real) ((real)->flag == NAN_FLAG)
|
34
34
|
#define POS_INF(real) ((real)->flag == POS_INF_FLAG)
|
35
35
|
#define NEG_INF(real) ((real)->flag == NEG_INF_FLAG)
|
36
|
+
#define REAL(real) ((real)->flag == REAL_FLAG)
|
36
37
|
|
37
38
|
#define ZERO(real) (REAL(real) && (mpz_sgn((real)->num) == 0))
|
38
39
|
#define POS(real) (POS_INF(real) || (REAL(real) && (mpz_sgn((real)->num) == 1)))
|
data/ext/number/real.c
CHANGED
@@ -53,30 +53,30 @@ void init_real_tmp_nums ()
|
|
53
53
|
}
|
54
54
|
|
55
55
|
/*
|
56
|
-
* Pads num with
|
56
|
+
* Pads num with n additional zeros.
|
57
57
|
*
|
58
|
-
* num: (1234),
|
58
|
+
* num: (1234), n: 2 => num: (123400)
|
59
59
|
*/
|
60
|
-
void num_pad (mpz_t num, int
|
60
|
+
void num_pad (mpz_t num, int n)
|
61
61
|
{
|
62
|
-
mpz_ui_pow_ui(tmp_num_pad, 10,
|
62
|
+
mpz_ui_pow_ui(tmp_num_pad, 10, n);
|
63
63
|
mpz_mul(num, num, tmp_num_pad);
|
64
64
|
}
|
65
65
|
|
66
66
|
/*
|
67
|
-
* Truncates num by
|
67
|
+
* Truncates num by n digits, rounding the rightmost remaining digit
|
68
68
|
* using round_mode.
|
69
69
|
*
|
70
|
-
* num: (12345),
|
70
|
+
* num: (12345), n: 3, round_mode: ROUND_UP => num: (13)
|
71
71
|
*/
|
72
|
-
void num_round (mpz_t num, int
|
72
|
+
void num_round (mpz_t num, int n, int round_mode)
|
73
73
|
{
|
74
|
-
if (
|
74
|
+
if (n <= 0)
|
75
75
|
{
|
76
76
|
return;
|
77
77
|
}
|
78
78
|
|
79
|
-
mpz_ui_pow_ui(tmp_num_round, 10,
|
79
|
+
mpz_ui_pow_ui(tmp_num_round, 10, n);
|
80
80
|
|
81
81
|
switch (round_mode)
|
82
82
|
{
|
@@ -90,7 +90,7 @@ void num_round (mpz_t num, int overrun, int round_mode)
|
|
90
90
|
|
91
91
|
case ROUND_NEAREST:
|
92
92
|
// fix this
|
93
|
-
//mpz_ui_pow_ui(tmp_num_round, 10,
|
93
|
+
//mpz_ui_pow_ui(tmp_num_round, 10, n);
|
94
94
|
mpz_fdiv_q(num, num, tmp_num_round);
|
95
95
|
//mpz_sub_ui(num, num, 5);
|
96
96
|
//mpz_fdiv_q_ui(num, num, 10);
|
@@ -111,10 +111,12 @@ void num_round (mpz_t num, int overrun, int round_mode)
|
|
111
111
|
*/
|
112
112
|
long num_len (mpz_t num)
|
113
113
|
{
|
114
|
-
|
114
|
+
int base = 10;
|
115
|
+
int sign = (mpz_sgn(num) == -1);
|
116
|
+
char buf[mpz_sizeinbase(num, base) + sign + 1];
|
115
117
|
|
116
|
-
mpz_get_str(buf,
|
117
|
-
return strlen(buf) -
|
118
|
+
mpz_get_str(buf, base, num);
|
119
|
+
return strlen(buf) - sign;
|
118
120
|
}
|
119
121
|
|
120
122
|
/*
|
@@ -135,11 +137,30 @@ void real_free (Real* real)
|
|
135
137
|
}
|
136
138
|
|
137
139
|
/*
|
138
|
-
* Returns the
|
140
|
+
* Returns the size of the string representation of real as a long.
|
139
141
|
*/
|
140
142
|
long real_strlen (Real* real)
|
141
143
|
{
|
142
|
-
|
144
|
+
switch (real->flag)
|
145
|
+
{
|
146
|
+
case NAN_FLAG:
|
147
|
+
return 2;
|
148
|
+
|
149
|
+
case POS_INF_FLAG:
|
150
|
+
case NEG_INF_FLAG:
|
151
|
+
return 4;
|
152
|
+
|
153
|
+
case REAL_FLAG:;
|
154
|
+
char buf[100];
|
155
|
+
sprintf(buf, "%ld", real->exp);
|
156
|
+
|
157
|
+
int sign = (mpz_sgn(real->num) == -1);
|
158
|
+
int digits = num_len(real->num);
|
159
|
+
int colon = 1;
|
160
|
+
int exp = strlen(buf);
|
161
|
+
|
162
|
+
return sign + digits + colon + exp;
|
163
|
+
}
|
143
164
|
}
|
144
165
|
|
145
166
|
/*
|
@@ -147,19 +168,34 @@ long real_strlen (Real* real)
|
|
147
168
|
*
|
148
169
|
* real: (561:1) => str: "561:1"
|
149
170
|
* real: (-3:-2) => str: "-3:-2"
|
171
|
+
* real: (+∞) => str: "+∞"
|
172
|
+
* real: (ø) => str: "ø"
|
150
173
|
*/
|
151
174
|
void real_print (char* buf, Real* real)
|
152
175
|
{
|
153
|
-
|
154
|
-
|
155
|
-
if (!REAL(real))
|
176
|
+
switch (real->flag)
|
156
177
|
{
|
157
|
-
|
158
|
-
|
178
|
+
case NAN_FLAG:
|
179
|
+
sprintf(buf, "ø");
|
180
|
+
break;
|
181
|
+
|
182
|
+
case POS_INF_FLAG:
|
183
|
+
sprintf(buf, "+∞");
|
184
|
+
break;
|
185
|
+
|
186
|
+
case NEG_INF_FLAG:
|
187
|
+
sprintf(buf, "-∞");
|
188
|
+
break;
|
189
|
+
|
190
|
+
case REAL_FLAG:;
|
191
|
+
int base = 10;
|
192
|
+
int sign = 1;
|
193
|
+
char num_buf[num_len(real->num) + sign + 1];
|
194
|
+
|
195
|
+
mpz_get_str(num_buf, base, real->num);
|
196
|
+
sprintf(buf, "%s:%ld", num_buf, real->exp);
|
197
|
+
break;
|
159
198
|
}
|
160
|
-
|
161
|
-
mpz_get_str(num_buf, 10, real->num);
|
162
|
-
sprintf(buf, "%s:%ld", num_buf, real->exp);
|
163
199
|
}
|
164
200
|
|
165
201
|
/*
|
@@ -192,8 +228,15 @@ void real_pad_tmps (Real* a, Real* b, long* exp, long* len)
|
|
192
228
|
num_pad(b_tmp, -pad);
|
193
229
|
}
|
194
230
|
|
195
|
-
|
196
|
-
|
231
|
+
if (exp != NULL)
|
232
|
+
{
|
233
|
+
*exp = max(a->exp, b->exp);
|
234
|
+
}
|
235
|
+
|
236
|
+
if (len != NULL)
|
237
|
+
{
|
238
|
+
*len = max(a_len, b_len);
|
239
|
+
}
|
197
240
|
}
|
198
241
|
|
199
242
|
/*
|
@@ -225,9 +268,6 @@ int real_positive_p (Real* real)
|
|
225
268
|
*/
|
226
269
|
int real_cmp (Real* a, Real* b)
|
227
270
|
{
|
228
|
-
long exp;
|
229
|
-
long len;
|
230
|
-
|
231
271
|
if (!REAL(a) || !REAL(b))
|
232
272
|
{
|
233
273
|
return (NaN(a) || NaN(b)) ? 0 : POS_INF(a) ? (POS_INF(b) ? 0 : 1) : POS_INF(b) ? -1 : NEG_INF(a) ? (NEG_INF(b) ? 0 : -1) : 1;
|
@@ -245,7 +285,7 @@ int real_cmp (Real* a, Real* b)
|
|
245
285
|
return (a_sign == -1) ? ((a->exp < b->exp) ? 1 : -1) : ((a->exp > b->exp) ? 1 : -1);
|
246
286
|
}
|
247
287
|
|
248
|
-
real_pad_tmps(a, b,
|
288
|
+
real_pad_tmps(a, b, NULL, NULL);
|
249
289
|
|
250
290
|
return mpz_cmp(a_tmp, b_tmp);
|
251
291
|
}
|
@@ -310,9 +350,9 @@ Real* real_alloc ()
|
|
310
350
|
/*
|
311
351
|
* Returns a pointer to a newly allocated Real representing NaN, +∞, or -∞.
|
312
352
|
*
|
313
|
-
* flag:
|
353
|
+
* flag: NAN_FLAG => real: (ø)
|
314
354
|
* flag: POS_INF_FLAG => real: (+∞)
|
315
|
-
* flag:
|
355
|
+
* flag: NEG_INF_FLAG => real: (-∞)
|
316
356
|
*/
|
317
357
|
Real* real_new_flagged (int flag)
|
318
358
|
{
|
@@ -329,7 +369,7 @@ Real* real_new_flagged (int flag)
|
|
329
369
|
* any trailing zero digits.
|
330
370
|
*
|
331
371
|
* num: (123), exp: 3 => real: (123:3)
|
332
|
-
* num: (-234), exp:
|
372
|
+
* num: (-234), exp: 5 => real: (-234:5)
|
333
373
|
* num: (1000), exp: 4 => real: (1:4)
|
334
374
|
*/
|
335
375
|
Real* real_new_exact (mpz_t num, long exp)
|
@@ -337,7 +377,7 @@ Real* real_new_exact (mpz_t num, long exp)
|
|
337
377
|
Real* real = real_alloc();
|
338
378
|
|
339
379
|
real->exp = exp;
|
340
|
-
real->flag =
|
380
|
+
real->flag = REAL_FLAG;
|
341
381
|
|
342
382
|
mpz_init(real->num);
|
343
383
|
|
@@ -376,11 +416,9 @@ Real* real_new_exact (mpz_t num, long exp)
|
|
376
416
|
*/
|
377
417
|
Real* real_new_rounded (mpz_t num, long exp, int round_mode)
|
378
418
|
{
|
419
|
+
long overrun = num_len(num) - digs;
|
379
420
|
mpz_set(tmp_real_new_rounded, num);
|
380
421
|
|
381
|
-
long len = num_len(num);
|
382
|
-
long overrun = len - digs;
|
383
|
-
|
384
422
|
if (overrun > 0)
|
385
423
|
{
|
386
424
|
num_round(tmp_real_new_rounded, overrun, round_mode);
|
@@ -391,14 +429,17 @@ Real* real_new_rounded (mpz_t num, long exp, int round_mode)
|
|
391
429
|
|
392
430
|
/*
|
393
431
|
* Returns a pointer to a newly allocated Real with the value represented by
|
394
|
-
* the given string and exp.
|
432
|
+
* the given string and exp. The string must contain only an optional negative
|
433
|
+
* followed by one or more digits between 0 and 9.
|
395
434
|
*
|
396
435
|
* str: "3456", exp: 2 => real: (3456:2)
|
397
436
|
* str: "-234", exp: -1 => real: (-234:-1)
|
398
437
|
*/
|
399
438
|
Real* real_from_str (char* num_str, long exp)
|
400
439
|
{
|
401
|
-
|
440
|
+
int base = 10;
|
441
|
+
mpz_set_str(tmp_real_from_str, num_str, base);
|
442
|
+
|
402
443
|
return real_new_exact(tmp_real_from_str, exp);
|
403
444
|
}
|
404
445
|
|
@@ -409,16 +450,19 @@ Real* real_from_str (char* num_str, long exp)
|
|
409
450
|
*/
|
410
451
|
Real* real_from_mpfr (mpfr_t num, int round_mode)
|
411
452
|
{
|
412
|
-
char buf[10000];
|
413
|
-
mpfr_exp_t exp;
|
414
|
-
|
415
453
|
if (!mpfr_number_p(num))
|
416
454
|
{
|
417
|
-
return real_new_flagged(mpfr_nan_p(num) ?
|
455
|
+
return real_new_flagged(mpfr_nan_p(num) ? NAN_FLAG : (mpfr_sgn(num) == 1) ? POS_INF_FLAG : NEG_INF_FLAG);
|
418
456
|
}
|
419
457
|
|
420
|
-
|
421
|
-
|
458
|
+
mpfr_exp_t exp;
|
459
|
+
int base = 10;
|
460
|
+
int sign = 1;
|
461
|
+
int digits = digs + 5;
|
462
|
+
char buf[digits + sign + 1];
|
463
|
+
|
464
|
+
mpfr_get_str(buf, &exp, base, digits, num, MPFR_RNDN);
|
465
|
+
mpz_set_str(tmp_real_from_mpfr, buf, base);
|
422
466
|
|
423
467
|
return real_new_rounded(tmp_real_from_mpfr, (long)exp, round_mode);
|
424
468
|
}
|
@@ -428,7 +472,7 @@ Real* real_from_mpfr (mpfr_t num, int round_mode)
|
|
428
472
|
*/
|
429
473
|
Real* real_nan ()
|
430
474
|
{
|
431
|
-
return real_new_flagged(
|
475
|
+
return real_new_flagged(NAN_FLAG);
|
432
476
|
}
|
433
477
|
|
434
478
|
/*
|
data/ext/number/real_bounds.c
CHANGED
@@ -19,6 +19,23 @@ void real_bounds_free (RealBounds* bounds)
|
|
19
19
|
}
|
20
20
|
}
|
21
21
|
|
22
|
+
RealBounds* real_bounds_new ()
|
23
|
+
{
|
24
|
+
RealBounds* bounds = malloc(sizeof(RealBounds));
|
25
|
+
|
26
|
+
if (bounds == NULL)
|
27
|
+
{
|
28
|
+
return NULL;
|
29
|
+
}
|
30
|
+
|
31
|
+
memset(bounds, 0, sizeof(RealBounds));
|
32
|
+
|
33
|
+
bounds->min = real_pos_inf();
|
34
|
+
bounds->max = real_neg_inf();
|
35
|
+
|
36
|
+
return bounds;
|
37
|
+
}
|
38
|
+
|
22
39
|
void real_bounds_update (RealBounds* bounds, Real* real, int closed)
|
23
40
|
{
|
24
41
|
int min_cmp;
|
@@ -42,20 +59,3 @@ void real_bounds_update (RealBounds* bounds, Real* real, int closed)
|
|
42
59
|
|
43
60
|
real_free(real);
|
44
61
|
}
|
45
|
-
|
46
|
-
RealBounds* real_bounds_new ()
|
47
|
-
{
|
48
|
-
RealBounds* bounds = malloc(sizeof(RealBounds));
|
49
|
-
|
50
|
-
if (bounds == NULL)
|
51
|
-
{
|
52
|
-
return NULL;
|
53
|
-
}
|
54
|
-
|
55
|
-
memset(bounds, 0, sizeof(RealBounds));
|
56
|
-
|
57
|
-
bounds->min = real_pos_inf();
|
58
|
-
bounds->max = real_neg_inf();
|
59
|
-
|
60
|
-
return bounds;
|
61
|
-
}
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: number
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.9.
|
5
|
+
version: 0.9.11
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Jesse Sielaff
|
@@ -12,7 +12,7 @@ autorequire:
|
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
14
|
|
15
|
-
date: 2011-
|
15
|
+
date: 2011-10-19 00:00:00 Z
|
16
16
|
dependencies: []
|
17
17
|
|
18
18
|
description: The Number gem is intended to be a drop-in replacement for Ruby's Numeric classes when arbitrary-precision complex interval calculations are warranted. The basis of the arbitrary-precision calculations is the GNU MP, MPFR, and MPC libraries.
|