1
5
6
9
10# include "mpmathdouble.h"
11
12# define PI 3.1415926535897932384626433832795028841971
13# define fraction_multiplier 4096.0
14# define angle_multiplier 16.0
15# define coef_bound ((7.0/3.0)*fraction_multiplier)
16# define fraction_threshold 0.04096
17# define half_fraction_threshold (fraction_threshold/2)
18# define scaled_threshold 0.000122
19# define half_scaled_threshold (scaled_threshold/2)
20# define near_zero_angle (0.0256*angle_multiplier)
21# define p_over_v_threshold 0x80000
22# define equation_threshold 0.001
23# define warning_limit pow(2.0,52.0)
24# define epsilon pow(2.0,-52.0)
25# define unity 1.0
26# define two 2.0
27# define three 3.0
28# define half_unit 0.5
29# define three_quarter_unit 0.75
30# define EL_GORDO (DBL_MAX / 2.0 - 1.0)
31# define negative_EL_GORDO (-EL_GORDO)
32# define one_third_EL_GORDO (EL_GORDO / 3.0)
33# define fraction_half (0.5*fraction_multiplier)
34# define fraction_one (1.0*fraction_multiplier)
35# define fraction_two (2.0*fraction_multiplier)
36# define fraction_three (3.0*fraction_multiplier)
37# define fraction_four (4.0*fraction_multiplier)
38# define no_crossing (fraction_one + 1)
39# define one_crossing fraction_one
40# define zero_crossing 0
41# define one_eighty_deg (180.0*angle_multiplier)
42# define negative_one_eighty_deg (-180.0*angle_multiplier)
43# define three_sixty_deg (360.0*angle_multiplier)
44# define odd(A) (abs(A) % 2 == 1)
45# define two_to_the(A) (1<<(unsigned)(A))
46# define set_cur_cmd(A) mp->cur_mod_->command = (A)
47# define set_cur_mod(A) mp->cur_mod_->data.n.data.dval = (A)
48
49
57
58static inline double mp_double_make_fraction (double p, double q) {
59
60 return p == 0.0 ? 0.0 : (p / q) * fraction_multiplier;
61}
62
63
64
65
66static inline double mp_double_take_fraction(double p, double q) {
67
68 return p == 0.0 ? 0.0 : q == 0.0 ? 0.0 : (p * q) / fraction_multiplier;
69}
70
71static inline double mp_double_make_scaled(double p, double q) {
72
73 return p == 0.0 ? 0.0 : p / q;
74}
75
76static void mp_double_allocate_number(MP mp, mp_number *n, mp_number_type t)
77{
78 (void) mp;
79 n->data.dval = 0.0;
80 n->type = t;
81}
82
83static void mp_double_allocate_clone(MP mp, mp_number *n, mp_number_type t, mp_number *v)
84{
85 (void) mp;
86 n->type = t;
87 n->data.dval = v->data.dval;
88}
89
90static void mp_double_allocate_abs(MP mp, mp_number *n, mp_number_type t, mp_number *v)
91{
92 (void) mp;
93 n->type = t;
94 n->data.dval = fabs(v->data.dval);
95}
96
97static void mp_double_allocate_double(MP mp, mp_number *n, double v)
98{
99 (void) mp;
100 n->type = mp_scaled_type;
101 n->data.dval = v;
102}
103
104static void mp_double_free_number(MP mp, mp_number *n)
105{
106 (void) mp;
107 n->type = mp_nan_type;
108}
109
110static void mp_double_set_from_int(mp_number *A, int B)
111{
112 A->data.dval = B;
113}
114
115static void mp_double_set_from_boolean(mp_number *A, int B)
116{
117 A->data.dval = B;
118}
119
120static void mp_double_set_from_scaled(mp_number *A, int B)
121{
122 A->data.dval = B == 0 ? 0.0 : B / 65536.0;
123}
124
125static void mp_double_set_from_double(mp_number *A, double B)
126{
127 A->data.dval = B;
128}
129
130static void mp_double_set_from_addition(mp_number *A, mp_number *B, mp_number *C)
131{
132 A->data.dval = B->data.dval + C->data.dval;
133}
134
135static void mp_double_set_half_from_addition(mp_number *A, mp_number *B, mp_number *C)
136{
137 A->data.dval = (B->data.dval + C->data.dval) / 2.0;
138}
139
140static void mp_double_set_from_subtraction(mp_number *A, mp_number *B, mp_number *C)
141{
142 A->data.dval = B->data.dval - C->data.dval;
143}
144
145static void mp_double_set_half_from_subtraction(mp_number *A, mp_number *B, mp_number *C)
146{
147 A->data.dval = (B->data.dval - C->data.dval) / 2.0;
148}
149
150static void mp_double_set_from_div(mp_number *A, mp_number *B, mp_number *C)
151{
152 A->data.dval = B->data.dval == 0.0 ? 0.0 : B->data.dval / C->data.dval;
153}
154
155static void mp_double_set_from_mul(mp_number *A, mp_number *B, mp_number *C)
156{
157 A->data.dval = B->data.dval == 0.0 || C->data.dval == 0.0 ? 0.0 : B->data.dval * C->data.dval;
158}
159
160static void mp_double_set_from_int_div(mp_number *A, mp_number *B, int C)
161{
162 A->data.dval = B->data.dval == 0.0 ? 0.0 : B->data.dval / C;
163}
164
165static void mp_double_set_from_int_mul(mp_number *A, mp_number *B, int C)
166{
167 A->data.dval = B->data.dval == 0.0 || C == 0 ? 0.0 : B->data.dval * C;
168}
169
170static void mp_double_set_from_of_the_way(MP mp, mp_number *A, mp_number *t, mp_number *B, mp_number *C)
171{
172 (void) mp;
173 A->data.dval = B->data.dval - mp_double_take_fraction(B->data.dval - C->data.dval, t->data.dval);
174}
175
176static void mp_double_negate(mp_number *A)
177{
178 if (A->data.dval == -0.0) {
179 A->data.dval = 0.0;
180 } else if (A->data.dval != 0.0) {
181 A->data.dval = -A->data.dval;
182 }
183}
184
185static void mp_double_add(mp_number *A, mp_number *B)
186{
187 A->data.dval += B->data.dval;
188}
189
190static void mp_double_subtract(mp_number *A, mp_number *B)
191{
192 A->data.dval -= B->data.dval;
193}
194
195static void mp_double_half(mp_number *A)
196{
197 if (A->data.dval != 0.0) {
198 A->data.dval /= 2.0;
199 }
200}
201
202static void mp_double_double(mp_number *A)
203{
204 if (A->data.dval != 0.0) {
205 A->data.dval *= 2.0;
206 }
207}
208
209static void mp_double_add_scaled(mp_number *A, int B)
210{
211
212 A->data.dval += (B / 65536.0);
213}
214
215static void mp_double_multiply_int(mp_number *A, int B)
216{
217 if (A->data.dval != 0.0) {
218 A->data.dval *= (double) B;
219 }
220}
221
222static void mp_double_divide_int(mp_number *A, int B)
223{
224 if (A->data.dval != 0.0) {
225 A->data.dval /= (double) B;
226 }
227}
228
229static void mp_double_abs(mp_number *A)
230{
231 A->data.dval = fabs(A->data.dval);
232}
233
234static void mp_double_clone(mp_number *A, mp_number *B)
235{
236 A->data.dval = B->data.dval;
237}
238
239static void mp_double_negated_clone(mp_number *A, mp_number *B)
240{
241 A->data.dval = -B->data.dval;
242 if (A->data.dval == -0.0) {
243 A->data.dval = 0.0;
244 }
245}
246
247static void mp_double_abs_clone(mp_number *A, mp_number *B)
248{
249 A->data.dval = fabs(B->data.dval);
250}
251
252static void mp_double_swap(mp_number *A, mp_number *B)
253{
254 double swap_tmp = A->data.dval;
255 A->data.dval = B->data.dval;
256 B->data.dval = swap_tmp;
257}
258
259static void mp_double_fraction_to_scaled(mp_number *A)
260{
261 A->type = mp_scaled_type;
262 if (A->data.dval != 0.0) {
263 A->data.dval /= fraction_multiplier;
264 }
265}
266
267static void mp_double_angle_to_scaled(mp_number *A)
268{
269 A->type = mp_scaled_type;
270 if (A->data.dval != 0.0) {
271 A->data.dval /= angle_multiplier;
272 }
273}
274
275static void mp_double_scaled_to_fraction(mp_number *A)
276{
277 A->type = mp_fraction_type;
278 if (A->data.dval != 0.0) {
279 A->data.dval *= fraction_multiplier;
280 }
281}
282
283static void mp_double_scaled_to_angle(mp_number *A)
284{
285 A->type = mp_angle_type;
286 if (A->data.dval != 0.0) {
287 A->data.dval *= angle_multiplier;
288 }
289}
290
291static int mp_double_to_scaled(mp_number *A)
292{
293 return (int) lround(A->data.dval * 65536.0);
294}
295
296static int mp_double_to_int(mp_number *A)
297{
298 return (int) (A->data.dval);
299}
300
301static int mp_double_to_boolean(mp_number *A)
302{
303 return (int) (A->data.dval);
304}
305
306static double mp_double_to_double(mp_number *A)
307{
308 return A->data.dval;
309}
310
311static int mp_double_odd(mp_number *A)
312{
313 return odd((int) lround(A->data.dval));
314}
315
316static int mp_double_equal(mp_number *A, mp_number *B)
317{
318 return A->data.dval == B->data.dval;
319}
320
321static int mp_double_greater(mp_number *A, mp_number *B)
322{
323 return A->data.dval > B->data.dval;
324}
325
326static int mp_double_less(mp_number *A, mp_number *B)
327{
328 return A->data.dval < B->data.dval;
329}
330
331static int mp_double_non_equal_abs(mp_number *A, mp_number *B)
332{
333 return fabs(A->data.dval) != fabs(B->data.dval);
334}
335
336static char *mp_double_number_tostring(MP mp, mp_number *n)
337{
338 static char set[64];
339 int l = 0;
340 char *ret = mp_memory_allocate(64);
341 (void) mp;
342 snprintf(set, 64, mp->less_digits ? "%.3g" : "%.17g", n->data.dval);
343 while (set[l] == ' ') {
344 l++;
345 }
346 strcpy(ret, set+l);
347 return ret;
348}
349
350static void mp_double_print_number(MP mp, mp_number *n)
351{
352 char *str = mp_double_number_tostring(mp, n);
353 mp_print_e_str(mp, str);
354 mp_memory_free(str);
355}
356
357static void mp_double_slow_add(MP mp, mp_number *ret, mp_number *x_orig, mp_number *y_orig)
358{
359 double x = x_orig->data.dval;
360 double y = y_orig->data.dval;
361 if (x >= 0.0) {
362 if (y <= EL_GORDO - x) {
363 ret->data.dval = x + y;
364 } else {
365 mp->arith_error = 1;
366 ret->data.dval = EL_GORDO;
367 }
368 } else if (-y <= EL_GORDO + x) {
369 ret->data.dval = x + y;
370 } else {
371 mp->arith_error = 1;
372 ret->data.dval = negative_EL_GORDO;
373 }
374}
375
376static void mp_double_number_make_fraction(MP mp, mp_number *ret, mp_number *p, mp_number *q) {
377 (void) mp;
378 ret->data.dval = mp_double_make_fraction(p->data.dval, q->data.dval);
379}
380
381static void mp_double_number_take_fraction(MP mp, mp_number *ret, mp_number *p, mp_number *q) {
382 (void) mp;
383 ret->data.dval = mp_double_take_fraction(p->data.dval, q->data.dval);
384}
385
386static void mp_double_number_take_scaled(MP mp, mp_number *ret, mp_number *p_orig, mp_number *q_orig)
387{
388 (void) mp;
389 ret->data.dval = p_orig->data.dval * q_orig->data.dval;
390}
391
392static void mp_double_number_make_scaled(MP mp, mp_number *ret, mp_number *p_orig, mp_number *q_orig)
393{
394 (void) mp;
395 ret->data.dval = p_orig->data.dval / q_orig->data.dval;
396}
397
398static void mp_wrapup_numeric_token(MP mp, unsigned char *start, unsigned char *stop)
399{
400 double result;
401 char *end = (char *) stop;
402 errno = 0;
403 result = strtod((char *) start, &end);
404 if (errno == 0) {
405 set_cur_mod(result);
406 if (result >= warning_limit) {
407 if (internal_value(mp_warning_check_internal).data.dval > 0 && (mp->scanner_status != mp_tex_flushing_state)) {
408 char msg[256];
409 snprintf(msg, 256, "Number is too large (%g)", result);
410 mp_error(
411 mp,
412 msg,
413 "Continue and I'll try to cope with that big value; but it might be dangerous."
414 "(Set warningcheck := 0 to suppress this message.)"
415 );
416 }
417 }
418 } else if (mp->scanner_status != mp_tex_flushing_state) {
419 mp_error(
420 mp,
421 "Enormous number has been reduced.",
422 "I could not handle this number specification probably because it is out of"
423 "range."
424 );
425 set_cur_mod(EL_GORDO);
426 }
427 set_cur_cmd(mp_numeric_command);
428}
429
430static void mp_double_aux_find_exponent(MP mp)
431{
432 if (mp->buffer[mp->cur_input.loc_field] == 'e' || mp->buffer[mp->cur_input.loc_field] == 'E') {
433 mp->cur_input.loc_field++;
434 if (!(mp->buffer[mp->cur_input.loc_field] == '+'
435 || mp->buffer[mp->cur_input.loc_field] == '-'
436 || mp->char_class[mp->buffer[mp->cur_input.loc_field]] == mp_digit_class)) {
437 mp->cur_input.loc_field--;
438 return;
439 }
440 if (mp->buffer[mp->cur_input.loc_field] == '+'
441 || mp->buffer[mp->cur_input.loc_field] == '-') {
442 mp->cur_input.loc_field++;
443 }
444 while (mp->char_class[mp->buffer[mp->cur_input.loc_field]] == mp_digit_class) {
445 mp->cur_input.loc_field++;
446 }
447 }
448}
449
450static void mp_double_scan_fractional_token(MP mp, int n)
451{
452 unsigned char *start = &mp->buffer[mp->cur_input.loc_field -1];
453 unsigned char *stop;
454 (void) n;
455 while (mp->char_class[mp->buffer[mp->cur_input.loc_field]] == mp_digit_class) {
456 mp->cur_input.loc_field++;
457 }
458 mp_double_aux_find_exponent(mp);
459 stop = &mp->buffer[mp->cur_input.loc_field-1];
460 mp_wrapup_numeric_token(mp, start, stop);
461}
462
463
467
468static void mp_double_scan_numeric_token(MP mp, int n)
469{
470 unsigned char *start = &mp->buffer[mp->cur_input.loc_field -1];
471 unsigned char *stop;
472 (void) n;
473 while (mp->char_class[mp->buffer[mp->cur_input.loc_field]] == mp_digit_class) {
474 mp->cur_input.loc_field++;
475 }
476 if (mp->buffer[mp->cur_input.loc_field] == '.' && mp->buffer[mp->cur_input.loc_field+1] != '.') {
477 mp->cur_input.loc_field++;
478 while (mp->char_class[mp->buffer[mp->cur_input.loc_field]] == mp_digit_class) {
479 mp->cur_input.loc_field++;
480 }
481 }
482 mp_double_aux_find_exponent(mp);
483 stop = &mp->buffer[mp->cur_input.loc_field-1];
484 mp_wrapup_numeric_token(mp, start, stop);
485}
486
487static void mp_double_velocity(MP mp, mp_number *ret, mp_number *st, mp_number *ct, mp_number *sf, mp_number *cf, mp_number *t)
488{
489 double acc, num, denom;
490 (void) mp;
491 acc = mp_double_take_fraction(st->data.dval - (sf->data.dval / 16.0), sf->data.dval - (st->data.dval / 16.0));
492 acc = mp_double_take_fraction(acc, ct->data.dval - cf->data.dval);
493 num = fraction_two + mp_double_take_fraction(acc, sqrt(2)*fraction_one);
494 denom = fraction_three
495 + mp_double_take_fraction(ct->data.dval, 3*fraction_half*(sqrt(5.0)-1.0))
496 + mp_double_take_fraction(cf->data.dval, 3*fraction_half*(3.0-sqrt(5.0)));
497 if (t->data.dval != unity) {
498 num = mp_double_make_scaled(num, t->data.dval);
499 }
500 if (num / 4 >= denom) {
501 ret->data.dval = fraction_four;
502 } else {
503 ret->data.dval = mp_double_make_fraction(num, denom);
504 }
505}
506
507static int mp_double_ab_vs_cd(mp_number *a_orig, mp_number *b_orig, mp_number *c_orig, mp_number *d_orig)
508{
509 double ab = a_orig->data.dval * b_orig->data.dval;
510 double cd = c_orig->data.dval * d_orig->data.dval;
511 if (ab > cd) {
512 return 1;
513 } else if (ab < cd) {
514 return -1;
515 } else {
516 return 0;
517 }
518}
519
520static void mp_double_crossing_point(MP mp, mp_number *ret, mp_number *aa, mp_number *bb, mp_number *cc)
521{
522 double a = aa->data.dval;
523 double b = bb->data.dval;
524 double c = cc->data.dval;
525 (void) mp;
526 if (a < 0.0) {
527 ret->data.dval = zero_crossing;
528 return;
529 } else if (c >= 0.0) {
530 if (b >= 0.0) {
531 if (c > 0.0) {
532 ret->data.dval = no_crossing;
533 } else if ((a == 0.0) && (b == 0.0)) {
534 ret->data.dval = no_crossing;
535 } else {
536 ret->data.dval = one_crossing;
537 }
538 return;
539 } else if (a == 0.0) {
540 ret->data.dval = zero_crossing;
541 return;
542 }
543 } else if ((a == 0.0) && (b <= 0.0)) {
544 ret->data.dval = zero_crossing;
545 return;
546 }
547
548 {
549 double d = epsilon;
550 double x0 = a;
551 double x1 = a - b;
552 double x2 = b - c;
553 do {
554
555 double x = (x1 + x2) / 2 + 1E-12;
556 if (x1 - x0 > x0) {
557 x2 = x;
558 x0 += x0;
559 d += d;
560 } else {
561 double xx = x1 + x - x0;
562 if (xx > x0) {
563 x2 = x;
564 x0 += x0;
565 d += d;
566 } else {
567 x0 = x0 - xx;
568 if ((x <= x0) && (x + x2 <= x0)) {
569 ret->data.dval = no_crossing;
570 return;
571 }
572 x1 = x;
573 d = d + d + epsilon;
574 }
575 }
576 } while (d < fraction_one);
577 ret->data.dval = (d - fraction_one);
578 }
579}
580
581
586
587static int mp_double_unscaled(mp_number *x_orig)
588{
589 return (int) lround(x_orig->data.dval);
590}
591
592static void mp_double_floor(mp_number *i)
593{
594 i->data.dval = floor(i->data.dval);
595}
596
597static void mp_double_fraction_to_round_scaled(mp_number *x_orig)
598{
599 double x = x_orig->data.dval;
600 x_orig->type = mp_scaled_type;
601 x_orig->data.dval = x / fraction_multiplier;
602}
603
604static void mp_double_square_rt(MP mp, mp_number *ret, mp_number *x_orig)
605{
606 double x = x_orig->data.dval;
607 if (x > 0) {
608 ret->data.dval = sqrt(x);
609 } else {
610 if (x < 0) {
611 char msg[256];
612 char *xstr = mp_double_number_tostring(mp, x_orig);
613 snprintf(msg, 256, "Square root of %s has been replaced by 0", xstr);
614 mp_memory_free(xstr);
615 mp_error(
616 mp,
617 msg,
618 "Since I don't take square roots of negative numbers, I'm zeroing this one.\n"
619 "Proceed, with fingers crossed."
620 );
621 }
622 ret->data.dval = 0;
623 }
624}
625
626static void mp_double_pyth_add(MP mp, mp_number *ret, mp_number *a_orig, mp_number *b_orig)
627{
628 double a = fabs(a_orig->data.dval);
629 double b = fabs(b_orig->data.dval);
630 errno = 0;
631 ret->data.dval = sqrt(a*a + b*b);
632 if (errno) {
633 mp->arith_error = 1;
634 ret->data.dval = EL_GORDO;
635 }
636}
637
638static void mp_double_pyth_sub(MP mp, mp_number *ret, mp_number *a_orig, mp_number *b_orig)
639{
640 double a = fabs(a_orig->data.dval);
641 double b = fabs(b_orig->data.dval);
642 if (a > b) {
643 a = sqrt(a*a - b*b);
644 } else {
645 if (a < b) {
646 char msg[256];
647 char *astr = mp_double_number_tostring(mp, a_orig);
648 char *bstr = mp_double_number_tostring(mp, b_orig);
649 snprintf(msg, 256, "Pythagorean subtraction %s+-+%s has been replaced by 0", astr, bstr);
650 mp_memory_free(astr);
651 mp_memory_free(bstr);
652 mp_error(
653 mp,
654 msg,
655 "Since I don't take square roots of negative numbers, Im zeroing this one.\n"
656 "Proceed, with fingers crossed."
657 );
658 }
659 a = 0;
660 }
661 ret->data.dval = a;
662}
663
664static void mp_double_power_of(MP mp, mp_number *ret, mp_number *a_orig, mp_number *b_orig)
665{
666 errno = 0;
667 ret->data.dval = pow(a_orig->data.dval, b_orig->data.dval);
668 if (errno) {
669 mp->arith_error = 1;
670 ret->data.dval = EL_GORDO;
671 }
672}
673
674static void mp_double_m_log(MP mp, mp_number *ret, mp_number *x_orig)
675{
676 if (x_orig->data.dval > 0) {
677 ret->data.dval = log(x_orig->data.dval)*256.0;
678 } else {
679 char msg[256];
680 char *xstr = mp_double_number_tostring(mp, x_orig);
681 snprintf(msg, 256, "Logarithm of %s has been replaced by 0", xstr);
682 mp_memory_free(xstr);
683 mp_error(
684 mp,
685 msg,
686 "Since I don't take logs of non-positive numbers, I'm zeroing this one.\n"
687 "Proceed, with fingers crossed."
688 );
689 ret->data.dval = 0;
690 }
691}
692
693static void mp_double_m_exp(MP mp, mp_number *ret, mp_number *x_orig)
694{
695 errno = 0;
696 ret->data.dval = exp(x_orig->data.dval / 256.0);
697 if (errno) {
698 if (x_orig->data.dval > 0) {
699 mp->arith_error = 1;
700 ret->data.dval = EL_GORDO;
701 } else {
702 ret->data.dval = 0;
703 }
704 }
705}
706
707
720
721static void mp_double_n_arg(MP mp, mp_number *ret, mp_number *x_orig, mp_number *y_orig)
722{
723
731 if (x_orig->data.dval == 0.0 && y_orig->data.dval == 0.0) {
732 if (internal_value(mp_default_zero_angle_internal).data.dval < 0) {
733 mp_error(
734 mp,
735 "angle(0,0) is taken as zero",
736 "The 'angle' between two identical points is undefined. I'm zeroing this one.\n"
737 "Proceed, with fingers crossed."
738 );
739 ret->data.dval = internal_value(mp_default_zero_angle_internal).data.dval;
740 } else {
741 ret->data.dval = 0;
742 }
743 } else {
744 ret->type = mp_angle_type;
745 ret->data.dval = atan2(y_orig->data.dval, x_orig->data.dval) * (180.0 / PI) * angle_multiplier;
746 if (ret->data.dval == -0.0) {
747 ret->data.dval = 0.0;
748 }
749
750 }
751}
752
753static void mp_double_sin_cos(MP mp, mp_number *z_orig, mp_number *n_cos, mp_number *n_sin)
754{
755 double rad = (z_orig->data.dval / angle_multiplier);
756 (void) mp;
757 if ((rad == 90.0) || (rad == -270)){
758 n_cos->data.dval = 0.0;
759 n_sin->data.dval = fraction_multiplier;
760 } else if ((rad == -90.0) || (rad == 270.0)) {
761 n_cos->data.dval = 0.0;
762 n_sin->data.dval = -fraction_multiplier;
763 } else if ((rad == 180.0) || (rad == -180.0)) {
764 n_cos->data.dval = -fraction_multiplier;
765 n_sin->data.dval = 0.0;
766 } else {
767 rad = rad * PI / 180.0;
768 n_cos->data.dval = cos(rad) * fraction_multiplier;
769 n_sin->data.dval = sin(rad) * fraction_multiplier;
770 }
771}
772
773
778
779# define KK 100
780# define LL 37
781# define MM (1L<<30)
782# define mod_diff(x,y) (((x)-(y))&(MM-1))
783# define TT 70
784# define is_odd(x) ((x)&1)
785# define QUALITY 1009
786
787
790
791typedef struct mp_double_random_info {
792 long x[KK];
793 long buf[QUALITY];
794 long dummy;
795 long started;
796 long *ptr;
797} mp_double_random_info;
798
799static mp_double_random_info mp_double_random_data = {
800 .dummy = -1,
801 .started = -1,
802 .ptr = &mp_double_random_data.dummy
803};
804
805static void mp_double_aux_ran_array(long aa[], int n)
806{
807 int i, j;
808 for (j = 0; j < KK; j++) {
809 aa[j] = mp_double_random_data.x[j];
810 }
811 for (; j < n; j++) {
812 aa[j] = mod_diff(aa[j - KK], aa[j - LL]);
813 }
814 for (i = 0; i < LL; i++, j++) {
815 mp_double_random_data.x[i] = mod_diff(aa[j - KK], aa[j - LL]);
816 }
817 for (; i < KK; i++, j++) {
818 mp_double_random_data.x[i] = mod_diff(aa[j - KK], mp_double_random_data.x[i - LL]);
819 }
820}
821
822static void mp_double_aux_ran_start(long seed)
823{
824 int t, j;
825 long x[KK + KK - 1];
826 long ss = (seed+2) & (MM - 2);
827 for (j = 0; j < KK; j++) {
828
829 x[j] = ss;
830
831 ss <<= 1;
832 if (ss >= MM) {
833 ss -= MM - 2;
834 }
835 }
836
837 x[1]++;
838 for (ss = seed & (MM - 1), t = TT - 1; t;) {
839 for (j = KK - 1; j > 0; j--) {
840
841 x[j + j] = x[j];
842 x[j + j - 1] = 0;
843 }
844 for (j = KK + KK - 2; j >= KK; j--) {
845 x[j - (KK -LL)] = mod_diff(x[j - (KK - LL)], x[j]);
846 x[j - KK] = mod_diff(x[j - KK], x[j]);
847 }
848 if (is_odd(ss)) {
849
850 for (j = KK; j>0; j--) {
851 x[j] = x[j-1];
852 }
853 x[0] = x[KK];
854
855 x[LL] = mod_diff(x[LL], x[KK]);
856 }
857 if (ss) {
858 ss >>= 1;
859 } else {
860 t--;
861 }
862 }
863 for (j = 0; j < LL; j++) {
864 mp_double_random_data.x[j + KK - LL] = x[j];
865 }
866 for (;j < KK; j++) {
867 mp_double_random_data.x[j - LL] = x[j];
868 }
869 for (j = 0; j < 10; j++) {
870
871 mp_double_aux_ran_array(x, KK + KK - 1);
872 }
873 mp_double_random_data.ptr = &mp_double_random_data.started;
874}
875
876static long mp_double_aux_ran_arr_cycle(void)
877{
878 if (mp_double_random_data.ptr == &mp_double_random_data.dummy) {
879
880 mp_double_aux_ran_start(314159L);
881 }
882 mp_double_aux_ran_array(mp_double_random_data.buf, QUALITY);
883 mp_double_random_data.buf[KK] = -1;
884 mp_double_random_data.ptr = mp_double_random_data.buf + 1;
885 return mp_double_random_data.buf[0];
886}
887
888static void mp_double_init_randoms(MP mp, int seed)
889{
890 int k = 1;
891 int j = abs(seed);
892 int f = (int) fraction_one;
893 while (j >= f) {
894 j = j / 2;
895 }
896 for (int i = 0; i <= 54; i++) {
897 int jj = k;
898 k = j - k;
899 j = jj;
900 if (k < 0) {
901 k += f;
902 }
903 mp->randoms[(i * 21) % 55].data.dval = j;
904 }
905 mp_new_randoms(mp);
906 mp_new_randoms(mp);
907 mp_new_randoms(mp);
908
909 mp_double_aux_ran_start((unsigned long) seed);
910}
911
912static void mp_double_modulo(mp_number *a, mp_number *b)
913{
914 double tmp;
915 a->data.dval = modf((double) a->data.dval / (double) b->data.dval, &tmp) * (double) b->data.dval;
916}
917
918static void mp_double_aux_next_unif_random(MP mp, mp_number *ret)
919{
920 unsigned long int op = (unsigned) (*mp_double_random_data.ptr>=0? *mp_double_random_data.ptr++: mp_double_aux_ran_arr_cycle());
921 double a = op / (MM * 1.0);
922 (void) mp;
923 ret->data.dval = a;
924}
925
926static void mp_double_aux_next_random(MP mp, mp_number *ret)
927{
928 if ( mp->j_random==0) {
929 mp_new_randoms(mp);
930 } else {
931 mp->j_random = mp->j_random-1;
932 }
933 mp_double_clone(ret, &(mp->randoms[mp->j_random]));
934}
935
936static void mp_double_m_unif_rand(MP mp, mp_number *ret, mp_number *x_orig)
937{
938 mp_number x, abs_x, u, y;
939 mp_double_allocate_number(mp, &y, mp_fraction_type);
940 mp_double_allocate_clone(mp, &x, mp_scaled_type, x_orig);
941 mp_double_allocate_abs(mp, &abs_x, mp_scaled_type, &x);
942 mp_double_allocate_number(mp, &u, mp_scaled_type);
943 mp_double_aux_next_unif_random(mp, &u);
944 y.data.dval = abs_x.data.dval * u.data.dval;
945 mp_double_free_number(mp, &u);
946 if (mp_double_equal(&y, &abs_x)) {
947 mp_double_clone(ret, &((math_data *)mp->math)->md_zero_t);
948 } else if (mp_double_greater(&x, &((math_data *)mp->math)->md_zero_t)) {
949 mp_double_clone(ret, &y);
950 } else {
951 mp_double_negated_clone(ret, &y);
952 }
953 mp_double_free_number(mp, &abs_x);
954 mp_double_free_number(mp, &x);
955 mp_double_free_number(mp, &y);
956}
957
958static void mp_double_m_norm_rand(MP mp, mp_number *ret)
959{
960 mp_number abs_x, u, r, la, xa;
961 mp_double_allocate_number(mp, &la, mp_scaled_type);
962 mp_double_allocate_number(mp, &xa, mp_scaled_type);
963 mp_double_allocate_number(mp, &abs_x, mp_scaled_type);
964 mp_double_allocate_number(mp, &u, mp_scaled_type);
965 mp_double_allocate_number(mp, &r, mp_scaled_type);
966 do {
967 do {
968 mp_number v;
969 mp_double_allocate_number(mp, &v, mp_scaled_type);
970 mp_double_aux_next_random(mp, &v);
971 mp_double_subtract(&v, &((math_data *)mp->math)->md_fraction_half_t);
972 mp_double_number_take_fraction(mp, &xa, &((math_data *)mp->math)->md_sqrt_8_e_k, &v);
973 mp_double_free_number(mp, &v);
974 mp_double_aux_next_random(mp, &u);
975 mp_double_clone(&abs_x, &xa);
976 mp_double_abs(&abs_x);
977 } while (! mp_double_less(&abs_x, &u));
978 mp_double_number_make_fraction(mp, &r, &xa, &u);
979 mp_double_clone(&xa, &r);
980 mp_double_m_log(mp, &la, &u);
981 mp_double_set_from_subtraction(&la, &((math_data *)mp->math)->md_twelve_ln_2_k, &la);
982 } while (mp_double_ab_vs_cd(&((math_data *)mp->math)->md_one_k, &la, &xa, &xa) < 0);
983 mp_double_clone(ret, &xa);
984 mp_double_free_number(mp, &r);
985 mp_double_free_number(mp, &abs_x);
986 mp_double_free_number(mp, &la);
987 mp_double_free_number(mp, &xa);
988 mp_double_free_number(mp, &u);
989}
990
991static void mp_double_set_precision(MP mp)
992{
993 (void) mp;
994}
995
996static void mp_double_free_math(MP mp)
997{
998 mp_double_free_number(mp, &(mp->math->md_three_sixty_deg_t));
999 mp_double_free_number(mp, &(mp->math->md_one_eighty_deg_t));
1000 mp_double_free_number(mp, &(mp->math->md_negative_one_eighty_deg_t));
1001 mp_double_free_number(mp, &(mp->math->md_fraction_one_t));
1002 mp_double_free_number(mp, &(mp->math->md_zero_t));
1003 mp_double_free_number(mp, &(mp->math->md_half_unit_t));
1004 mp_double_free_number(mp, &(mp->math->md_three_quarter_unit_t));
1005 mp_double_free_number(mp, &(mp->math->md_unity_t));
1006 mp_double_free_number(mp, &(mp->math->md_two_t));
1007 mp_double_free_number(mp, &(mp->math->md_three_t));
1008 mp_double_free_number(mp, &(mp->math->md_one_third_inf_t));
1009 mp_double_free_number(mp, &(mp->math->md_inf_t));
1010 mp_double_free_number(mp, &(mp->math->md_negative_inf_t));
1011 mp_double_free_number(mp, &(mp->math->md_warning_limit_t));
1012 mp_double_free_number(mp, &(mp->math->md_one_k));
1013 mp_double_free_number(mp, &(mp->math->md_sqrt_8_e_k));
1014 mp_double_free_number(mp, &(mp->math->md_twelve_ln_2_k));
1015 mp_double_free_number(mp, &(mp->math->md_coef_bound_k));
1016 mp_double_free_number(mp, &(mp->math->md_coef_bound_minus_1));
1017 mp_double_free_number(mp, &(mp->math->md_fraction_threshold_t));
1018 mp_double_free_number(mp, &(mp->math->md_half_fraction_threshold_t));
1019 mp_double_free_number(mp, &(mp->math->md_scaled_threshold_t));
1020 mp_double_free_number(mp, &(mp->math->md_half_scaled_threshold_t));
1021 mp_double_free_number(mp, &(mp->math->md_near_zero_angle_t));
1022 mp_double_free_number(mp, &(mp->math->md_p_over_v_threshold_t));
1023 mp_double_free_number(mp, &(mp->math->md_equation_threshold_t));
1024 mp_memory_free(mp->math);
1025}
1026
1027math_data *mp_initialize_double_math(MP mp)
1028{
1029 math_data *math = (math_data *) mp_memory_allocate(sizeof(math_data));
1030
1031 math->md_allocate = mp_double_allocate_number;
1032 math->md_free = mp_double_free_number;
1033 math->md_allocate_clone = mp_double_allocate_clone;
1034 math->md_allocate_abs = mp_double_allocate_abs;
1035 math->md_allocate_double = mp_double_allocate_double;
1036
1037 mp_double_allocate_number(mp, &math->md_precision_default, mp_scaled_type);
1038 mp_double_allocate_number(mp, &math->md_precision_max, mp_scaled_type);
1039 mp_double_allocate_number(mp, &math->md_precision_min, mp_scaled_type);
1040
1041 mp_double_allocate_number(mp, &math->md_epsilon_t, mp_scaled_type);
1042 mp_double_allocate_number(mp, &math->md_inf_t, mp_scaled_type);
1043 mp_double_allocate_number(mp, &math->md_negative_inf_t, mp_scaled_type);
1044 mp_double_allocate_number(mp, &math->md_warning_limit_t, mp_scaled_type);
1045 mp_double_allocate_number(mp, &math->md_one_third_inf_t, mp_scaled_type);
1046 mp_double_allocate_number(mp, &math->md_unity_t, mp_scaled_type);
1047 mp_double_allocate_number(mp, &math->md_two_t, mp_scaled_type);
1048 mp_double_allocate_number(mp, &math->md_three_t, mp_scaled_type);
1049 mp_double_allocate_number(mp, &math->md_half_unit_t, mp_scaled_type);
1050 mp_double_allocate_number(mp, &math->md_three_quarter_unit_t, mp_scaled_type);
1051 mp_double_allocate_number(mp, &math->md_zero_t, mp_scaled_type);
1052
1053 mp_double_allocate_number(mp, &math->md_arc_tol_k, mp_fraction_type);
1054 mp_double_allocate_number(mp, &math->md_fraction_one_t, mp_fraction_type);
1055 mp_double_allocate_number(mp, &math->md_fraction_half_t, mp_fraction_type);
1056 mp_double_allocate_number(mp, &math->md_fraction_three_t, mp_fraction_type);
1057 mp_double_allocate_number(mp, &math->md_fraction_four_t, mp_fraction_type);
1058
1059 mp_double_allocate_number(mp, &math->md_three_sixty_deg_t, mp_angle_type);
1060 mp_double_allocate_number(mp, &math->md_one_eighty_deg_t, mp_angle_type);
1061 mp_double_allocate_number(mp, &math->md_negative_one_eighty_deg_t, mp_angle_type);
1062
1063 mp_double_allocate_number(mp, &math->md_one_k, mp_scaled_type);
1064 mp_double_allocate_number(mp, &math->md_sqrt_8_e_k, mp_scaled_type);
1065 mp_double_allocate_number(mp, &math->md_twelve_ln_2_k, mp_fraction_type);
1066 mp_double_allocate_number(mp, &math->md_coef_bound_k, mp_fraction_type);
1067 mp_double_allocate_number(mp, &math->md_coef_bound_minus_1, mp_fraction_type);
1068 mp_double_allocate_number(mp, &math->md_twelvebits_3, mp_scaled_type);
1069 mp_double_allocate_number(mp, &math->md_twentysixbits_sqrt2_t, mp_fraction_type);
1070 mp_double_allocate_number(mp, &math->md_twentyeightbits_d_t, mp_fraction_type);
1071 mp_double_allocate_number(mp, &math->md_twentysevenbits_sqrt2_d_t, mp_fraction_type);
1072
1073 mp_double_allocate_number(mp, &math->md_fraction_threshold_t, mp_fraction_type);
1074 mp_double_allocate_number(mp, &math->md_half_fraction_threshold_t, mp_fraction_type);
1075 mp_double_allocate_number(mp, &math->md_scaled_threshold_t, mp_scaled_type);
1076 mp_double_allocate_number(mp, &math->md_half_scaled_threshold_t, mp_scaled_type);
1077 mp_double_allocate_number(mp, &math->md_near_zero_angle_t, mp_angle_type);
1078 mp_double_allocate_number(mp, &math->md_p_over_v_threshold_t, mp_fraction_type);
1079 mp_double_allocate_number(mp, &math->md_equation_threshold_t, mp_scaled_type);
1080
1081 math->md_precision_default.data.dval = 16 * unity;
1082 math->md_precision_max.data.dval = 16 * unity;
1083 math->md_precision_min.data.dval = 16 * unity;
1084 math->md_epsilon_t.data.dval = epsilon;
1085 math->md_inf_t.data.dval = EL_GORDO;
1086 math->md_negative_inf_t.data.dval = negative_EL_GORDO;
1087 math->md_one_third_inf_t.data.dval = one_third_EL_GORDO;
1088 math->md_warning_limit_t.data.dval = warning_limit;
1089 math->md_unity_t.data.dval = unity;
1090 math->md_two_t.data.dval = two;
1091 math->md_three_t.data.dval = three;
1092 math->md_half_unit_t.data.dval = half_unit;
1093 math->md_three_quarter_unit_t.data.dval = three_quarter_unit;
1094 math->md_arc_tol_k.data.dval = (unity/4096);
1095 math->md_fraction_one_t.data.dval = fraction_one;
1096 math->md_fraction_half_t.data.dval = fraction_half;
1097 math->md_fraction_three_t.data.dval = fraction_three;
1098 math->md_fraction_four_t.data.dval = fraction_four;
1099 math->md_three_sixty_deg_t.data.dval = three_sixty_deg;
1100 math->md_one_eighty_deg_t.data.dval = one_eighty_deg;
1101 math->md_negative_one_eighty_deg_t.data.dval = negative_one_eighty_deg;
1102 math->md_one_k.data.dval = 1.0/64 ;
1103 math->md_sqrt_8_e_k.data.dval = 1.71552776992141359295;
1104 math->md_twelve_ln_2_k.data.dval = 8.31776616671934371292 * 256;
1105 math->md_coef_bound_k.data.dval = coef_bound;
1106 math->md_coef_bound_minus_1.data.dval = coef_bound - 1/65536.0;
1107 math->md_twelvebits_3.data.dval = 1365 / 65536.0;
1108 math->md_twentysixbits_sqrt2_t.data.dval = 94906266 / 65536.0;
1109 math->md_twentyeightbits_d_t.data.dval = 35596755 / 65536.0;
1110 math->md_twentysevenbits_sqrt2_d_t.data.dval = 25170707 / 65536.0;
1111 math->md_fraction_threshold_t.data.dval = fraction_threshold;
1112 math->md_half_fraction_threshold_t.data.dval = half_fraction_threshold;
1113 math->md_scaled_threshold_t.data.dval = scaled_threshold;
1114 math->md_half_scaled_threshold_t.data.dval = half_scaled_threshold;
1115 math->md_near_zero_angle_t.data.dval = near_zero_angle;
1116 math->md_p_over_v_threshold_t.data.dval = p_over_v_threshold;
1117 math->md_equation_threshold_t.data.dval = equation_threshold;
1118
1119 math->md_from_int = mp_double_set_from_int;
1120 math->md_from_boolean = mp_double_set_from_boolean;
1121 math->md_from_scaled = mp_double_set_from_scaled;
1122 math->md_from_double = mp_double_set_from_double;
1123 math->md_from_addition = mp_double_set_from_addition;
1124 math->md_half_from_addition = mp_double_set_half_from_addition;
1125 math->md_from_subtraction = mp_double_set_from_subtraction;
1126 math->md_half_from_subtraction = mp_double_set_half_from_subtraction;
1127 math->md_from_of_the_way = mp_double_set_from_of_the_way;
1128 math->md_from_div = mp_double_set_from_div;
1129 math->md_from_mul = mp_double_set_from_mul;
1130 math->md_from_int_div = mp_double_set_from_int_div;
1131 math->md_from_int_mul = mp_double_set_from_int_mul;
1132 math->md_negate = mp_double_negate;
1133 math->md_add = mp_double_add;
1134 math->md_subtract = mp_double_subtract;
1135 math->md_half = mp_double_half;
1136 math->md_do_double = mp_double_double;
1137 math->md_abs = mp_double_abs;
1138 math->md_clone = mp_double_clone;
1139 math->md_negated_clone = mp_double_negated_clone;
1140 math->md_abs_clone = mp_double_abs_clone;
1141 math->md_swap = mp_double_swap;
1142 math->md_add_scaled = mp_double_add_scaled;
1143 math->md_multiply_int = mp_double_multiply_int;
1144 math->md_divide_int = mp_double_divide_int;
1145 math->md_to_int = mp_double_to_int;
1146 math->md_to_boolean = mp_double_to_boolean;
1147 math->md_to_scaled = mp_double_to_scaled;
1148 math->md_to_double = mp_double_to_double;
1149 math->md_odd = mp_double_odd;
1150 math->md_equal = mp_double_equal;
1151 math->md_less = mp_double_less;
1152 math->md_greater = mp_double_greater;
1153 math->md_non_equal_abs = mp_double_non_equal_abs;
1154 math->md_round_unscaled = mp_double_unscaled;
1155 math->md_floor_scaled = mp_double_floor;
1156 math->md_fraction_to_round_scaled = mp_double_fraction_to_round_scaled;
1157 math->md_make_scaled = mp_double_number_make_scaled;
1158 math->md_make_fraction = mp_double_number_make_fraction;
1159 math->md_take_fraction = mp_double_number_take_fraction;
1160 math->md_take_scaled = mp_double_number_take_scaled;
1161 math->md_velocity = mp_double_velocity;
1162 math->md_n_arg = mp_double_n_arg;
1163 math->md_m_log = mp_double_m_log;
1164 math->md_m_exp = mp_double_m_exp;
1165 math->md_m_unif_rand = mp_double_m_unif_rand;
1166 math->md_m_norm_rand = mp_double_m_norm_rand;
1167 math->md_pyth_add = mp_double_pyth_add;
1168 math->md_pyth_sub = mp_double_pyth_sub;
1169 math->md_power_of = mp_double_power_of;
1170 math->md_fraction_to_scaled = mp_double_fraction_to_scaled;
1171 math->md_scaled_to_fraction = mp_double_scaled_to_fraction;
1172 math->md_scaled_to_angle = mp_double_scaled_to_angle;
1173 math->md_angle_to_scaled = mp_double_angle_to_scaled;
1174 math->md_init_randoms = mp_double_init_randoms;
1175 math->md_sin_cos = mp_double_sin_cos;
1176 math->md_slow_add = mp_double_slow_add;
1177 math->md_sqrt = mp_double_square_rt;
1178 math->md_print = mp_double_print_number;
1179 math->md_tostring = mp_double_number_tostring;
1180 math->md_modulo = mp_double_modulo;
1181 math->md_ab_vs_cd = mp_double_ab_vs_cd;
1182 math->md_crossing_point = mp_double_crossing_point;
1183 math->md_scan_numeric = mp_double_scan_numeric_token;
1184 math->md_scan_fractional = mp_double_scan_fractional_token;
1185
1186 math->md_free_math = mp_double_free_math;
1187 math->md_set_precision = mp_double_set_precision;
1188 return math;
1189}
1190 |