1
5
6# include "mpmathscaled.h"
7# include "mpstrings.h"
8
9# define coef_bound 0x25555555
10# define fraction_threshold 2685
11# define half_fraction_threshold 1342
12# define scaled_threshold 8
13# define half_scaled_threshold 4
14# define near_zero_angle 26844
15# define p_over_v_threshold 0x80000
16# define equation_threshold 64
17
18
23
24# define unity 0x10000
25# define two (2*unity)
26# define three (3*unity)
27# define half_unit (unity/2)
28# define three_quarter_unit (3*(unity/4))
29# define EL_GORDO 0x7FFFFFFF
30# define negative_EL_GORDO (-EL_GORDO)
31# define one_third_EL_GORDO 0x2AAAAAAA
32
33
34
35# define TWEXP31 2147483648.0
36# define TWEXP28 268435456.0
37# define TWEXP16 65536.0
38# define TWEXP_16 (1.0/65536.0)
39# define TWEXP_28 (1.0/268435456.0)
40# define no_crossing (fraction_one + 1)
41# define one_crossing fraction_one
42# define zero_crossing 0
43
44
50
51# define fraction_half 0x08000000
52# define fraction_one 0x10000000
53# define fraction_two 0x20000000
54# define fraction_three 0x30000000
55# define fraction_four 0x40000000
56
57
61
62# define negate_x 1
63# define negate_y 2
64# define switch_x_and_y 4
65# define first_octant 1
66# define second_octant (first_octant + switch_x_and_y)
67# define third_octant (first_octant + switch_x_and_y + negate_x)
68# define fourth_octant (first_octant + negate_x)
69# define fifth_octant (first_octant + negate_x + negate_y)
70# define sixth_octant (first_octant + switch_x_and_y + negate_x + negate_y)
71# define seventh_octant (first_octant + switch_x_and_y + negate_y)
72# define eighth_octant (first_octant + negate_y)
73# define forty_five_deg 0x02D00000
74# define ninety_deg 0x05A00000
75# define one_eighty_deg 0x0B400000
76# define negative_one_eighty_deg -0x0B400000
77# define three_sixty_deg 0x16800000
78# define odd(A) (abs(A)%2==1)
79# define two_to_the(A) (1<<(unsigned)(A))
80# define set_cur_cmd(A) mp->cur_mod_->command = (A)
81# define set_cur_mod(A) mp->cur_mod_->data.n.data.val = (A)
82
83static const int mp_m_spec_log[29] = {
84 0, 93032640, 38612034, 17922280, 8662214, 4261238, 2113709, 1052693, 525315,
85 262400, 131136, 65552, 32772, 16385, 8192, 4096, 2048, 1024, 512, 256, 128,
86 64, 32, 16, 8, 4, 2, 1, 1
87};
88
89static const int mp_m_spec_atan[27] = {
90 0, 27855475, 14718068, 7471121, 3750058, 1876857, 938658, 469357, 234682,
91 117342, 58671, 29335, 14668, 7334, 3667, 1833, 917, 458, 229, 115, 57, 29,
92 14, 7, 4, 2, 1
93};
94
95static int mp_scaled_aux_take_fraction (MP mp, int p, int q);
96static int mp_scaled_aux_make_fraction (MP mp, int p, int q);
97static int mp_scaled_round_unscaled (mp_number *x_orig);
98
99static void mp_scaled_allocate_number(MP mp, mp_number *n, mp_number_type t)
100{
101 (void) mp;
102 n->data.val = 0;
103 n->type = t;
104}
105
106static void mp_scaled_allocate_clone(MP mp, mp_number *n, mp_number_type t, mp_number *v)
107{
108 (void) mp;
109 n->type = t;
110 n->data.val = v->data.val;
111}
112
113static void mp_scaled_allocate_abs(MP mp, mp_number *n, mp_number_type t, mp_number *v)
114{
115 (void) mp;
116 n->type = t;
117 n->data.val = abs(v->data.val);
118}
119
120static void mp_scaled_allocate_double(MP mp, mp_number *n, double v)
121{
122 (void) mp;
123 n->type = mp_scaled_type;
124 n->data.val = (int) (v * 65536.0);
125}
126
127static void mp_scaled_free_number(MP mp, mp_number *n)
128{
129 (void) mp;
130 n->type = mp_nan_type;
131}
132
133static void mp_scaled_set_from_int(mp_number *A, int B)
134{
135 A->data.val = B * 65536;
136}
137
138static void mp_scaled_set_from_boolean(mp_number *A, int B)
139{
140 A->data.val = B;
141}
142
143static void mp_scaled_set_from_scaled(mp_number *A, int B)
144{
145 A->data.val = B;
146}
147
148static void mp_scaled_set_from_double(mp_number *A, double B)
149{
150 A->data.val = (int) (B * 65536.0);
151}
152
153static void mp_scaled_set_from_addition(mp_number *A, mp_number *B, mp_number *C)
154{
155 A->data.val = B->data.val + C->data.val;
156}
157
158static void mp_scaled_set_half_from_addition(mp_number *A, mp_number *B, mp_number *C)
159{
160 A->data.val = (B->data.val + C->data.val) / 2;
161}
162
163static void mp_scaled_set_from_subtraction(mp_number *A, mp_number *B, mp_number *C)
164{
165 A->data.val = B->data.val - C->data.val;
166}
167
168static void mp_scaled_set_half_from_subtraction(mp_number *A, mp_number *B, mp_number *C)
169{
170 A->data.val = (B->data.val - C->data.val) / 2;
171}
172
173static void mp_scaled_set_from_div(mp_number *A, mp_number *B, mp_number *C)
174{
175 A->data.val = B->data.val / C->data.val;
176}
177
178static void mp_scaled_set_from_mul(mp_number *A, mp_number *B, mp_number *C)
179{
180 A->data.val = B->data.val * C->data.val;
181}
182
183static void mp_scaled_set_from_int_div(mp_number *A, mp_number *B, int C)
184{
185 A->data.val = B->data.val / C;
186}
187
188static void mp_scaled_set_from_int_mul(mp_number *A, mp_number *B, int C)
189{
190 A->data.val = B->data.val * C;
191}
192
193static void mp_scaled_set_from_of_the_way(MP mp, mp_number *A, mp_number *t, mp_number *B, mp_number *C)
194{
195 (void) mp;
196 A->data.val = B->data.val - mp_scaled_aux_take_fraction(mp, (B->data.val - C->data.val), t->data.val);
197}
198
199static void mp_scaled_negate(mp_number *A)
200{
201 A->data.val = -A->data.val;
202}
203
204static void mp_scaled_add(mp_number *A, mp_number *B)
205{
206 A->data.val = A->data.val + B->data.val;
207}
208
209static void mp_scaled_subtract(mp_number *A, mp_number *B)
210{
211 A->data.val = A->data.val - B->data.val;
212}
213
214static void mp_scaled_half(mp_number *A)
215{
216 A->data.val = A->data.val / 2;
217}
218
219static void mp_scaled_double(mp_number *A)
220{
221 A->data.val = A->data.val + A->data.val;
222}
223
224static void mp_scaled_add_scaled(mp_number *A, int B)
225{
226
227 A->data.val = A->data.val + B;
228}
229
230static void mp_scaled_multiply_int(mp_number *A, int B)
231{
232 A->data.val = B * A->data.val;
233}
234
235static void mp_scaled_divide_int(mp_number *A, int B)
236{
237 A->data.val = A->data.val / B;
238}
239
240static void mp_scaled_abs(mp_number *A)
241{
242 A->data.val = abs(A->data.val);
243}
244
245static void mp_scaled_clone(mp_number *A, mp_number *B)
246{
247 A->data.val = B->data.val;
248}
249
250static void mp_scaled_negated_clone(mp_number *A, mp_number *B)
251{
252 A->data.val = -B->data.val;
253}
254
255static void mp_scaled_abs_clone(mp_number *A, mp_number *B)
256{
257 A->data.val = abs(B->data.val);
258}
259
260static void mp_scaled_swap(mp_number *A, mp_number *B)
261{
262 int swap_tmp = A->data.val;
263 A->data.val = B->data.val;
264 B->data.val = swap_tmp;
265}
266
267static void mp_scaled_fraction_to_scaled(mp_number *A)
268{
269 A->type = mp_scaled_type;
270 A->data.val = A->data.val / 4096;
271}
272
273static void mp_scaled_angle_to_scaled(mp_number *A)
274{
275 A->type = mp_scaled_type;
276 if (A->data.val >= 0) {
277 A->data.val = ( A->data.val + 8) / 16;
278 } else {
279 A->data.val = -((-A->data.val + 8) / 16);
280 }
281}
282
283static void mp_scaled_scaled_to_fraction(mp_number *A)
284{
285 A->type = mp_fraction_type;
286 A->data.val = A->data.val * 4096;
287}
288
289static void mp_scaled_scaled_to_angle(mp_number *A)
290{
291 A->type = mp_angle_type;
292 A->data.val = A->data.val * 16;
293}
294
295static int mp_scaled_to_int(mp_number *A)
296{
297 return A->data.val;
298}
299
300static int mp_scaled_to_scaled(mp_number *A)
301{
302 return A->data.val;
303}
304
305static int mp_scaled_to_boolean(mp_number *A)
306{
307 return A->data.val;
308}
309
310static double mp_scaled_to_double(mp_number *A)
311{
312 return A->data.val / 65536.0;
313}
314
315static int mp_scaled_odd(mp_number *A)
316{
317 return odd(mp_scaled_round_unscaled(A));
318}
319
320static int mp_scaled_equal(mp_number *A, mp_number *B) {
321 return A->data.val == B->data.val;
322}
323
324static int mp_scaled_greater(mp_number *A, mp_number *B)
325{
326 return A->data.val > B->data.val;
327}
328
329static int mp_scaled_less(mp_number *A, mp_number *B)
330{
331 return A->data.val < B->data.val;
332}
333
334static int mp_scaled_non_equal_abs(mp_number *A, mp_number *B)
335{
336 return abs(A->data.val) != abs(B->data.val);
337}
338
339
364
365
366
367static char *mp_string_scaled(MP mp, int s)
368{
369 static char scaled_string[32];
370 int i = 0;
371 (void) mp;
372 if (s < 0) {
373 scaled_string[i++] = '-';
374 s = -s;
375 }
376
377 snprintf ((scaled_string+i), 12, "%d", (int) (s / unity));
378 while (*(scaled_string+i)) {
379 i++;
380 }
381 s = 10 * (s % unity) + 5;
382 if (s != 5) {
383
384 int delta = 10;
385 scaled_string[i++] = '.';
386 do {
387
388 if (delta > unity) {
389 s = s + 0x8000 - (delta / 2);
390 }
391 scaled_string[i++] = (char) ((s / unity) + '0');
392 s = 10 * (s % unity);
393 delta = delta * 10;
394 } while (s > delta);
395 }
396 scaled_string[i] = '\0';
397 return scaled_string;
398}
399
400
404
405static void mp_scaled_slow_add(MP mp, mp_number *ret, mp_number *x_orig, mp_number *y_orig)
406{
407 int x = x_orig->data.val;
408 int y = y_orig->data.val;
409 if (x >= 0) {
410 if (y <= EL_GORDO - x) {
411 ret->data.val = x + y;
412 } else {
413 mp->arith_error = 1;
414 ret->data.val = EL_GORDO;
415 }
416 } else if (-y <= EL_GORDO + x) {
417 ret->data.val = x + y;
418 } else {
419 mp->arith_error = 1;
420 ret->data.val = negative_EL_GORDO;
421 }
422}
423
424
455
456
459
460static int mp_scaled_aux_make_fraction(MP mp, int p, int q)
461{
462 if (q == 0) {
463 mp_confusion (mp, "division by zero");
464 return 0;
465 } else {
466 double d = TWEXP28 * (double) p / (double) q;
467 if ((p ^ q) >= 0) {
468 d += 0.5;
469 if (d >= TWEXP31) {
470 mp->arith_error = 1;
471 return EL_GORDO;
472 } else {
473 int i = (int) d;
474 if (d == (double) i && (((q > 0 ? -q : q) & 0x7FFF) * (((i & 0x3FFF) << 1) - 1) & 0x800) != 0) {
475 --i;
476 }
477 return i;
478 }
479 } else {
480 d -= 0.5;
481 if (d <= -TWEXP31) {
482 mp->arith_error = 1;
483 return -negative_EL_GORDO;
484 } else {
485 int i = (int) d;
486 if (d == (double) i && (((q > 0 ? q : -q) & 0x7FFF) * (((i & 0x3FFF) << 1) + 1) & 0x800) != 0) {
487 ++i;
488 }
489 return i;
490 }
491 }
492 }
493}
494
495static void mp_scaled_make_fraction(MP mp, mp_number *ret, mp_number *p, mp_number *q)
496{
497 ret->data.val = mp_scaled_aux_make_fraction (mp, p->data.val, q->data.val);
498}
499
500
509
510static int mp_scaled_aux_take_fraction(MP mp, int p, int q)
511{
512 double d = (double) p *(double) q *TWEXP_28;
513 if ((p ^ q) >= 0) {
514 d += 0.5;
515 if (d >= TWEXP31) {
516 if (d != TWEXP31 || (((p & 0x7FFF) * (q & 0x7FFF)) & 040000) == 0) {
517 mp->arith_error = 1;
518 }
519 return EL_GORDO;
520 } else {
521 int i = (int) d;
522 if (d == (double) i && (((p & 0x7FFF) * (q & 0x7FFF)) & 0x4000) != 0) {
523 --i;
524 }
525 return i;
526 }
527 } else {
528 d -= 0.5;
529 if (d <= -TWEXP31) {
530 if (d != -TWEXP31 || ((-(p & 0x7FFF) * (q & 0x7FFF)) & 0x4000) == 0) {
531 mp->arith_error = 1;
532 }
533 return -negative_EL_GORDO;
534 } else {
535 int i = (int) d;
536 if (d == (double) i && ((-(p & 0x7FFF) * (q & 0x7FFF)) & 0x4000) != 0) {
537 ++i;
538 }
539 return i;
540 }
541 }
542}
543
544static void mp_scaled_take_fraction(MP mp, mp_number *ret, mp_number *p_orig, mp_number *q_orig)
545{
546 ret->data.val = mp_scaled_aux_take_fraction(mp, p_orig->data.val, q_orig->data.val);
547}
548
549
560
561static int mp_take_scaled(MP mp, int p, int q)
562{
563
564 double d = (double) p * (double) q * TWEXP_16;
565 if ((p ^ q) >= 0) {
566 d += 0.5;
567 if (d >= TWEXP31) {
568 if (d != TWEXP31 || (((p & 0x7FFF) * (q & 0x7FFF)) & 0x4000) == 0) {
569 mp->arith_error = 1;
570 }
571 return EL_GORDO;
572 } else {
573 int i = (int) d;
574 if (d == (double) i && (((p & 0x7FFF) * (q & 0x7FFF)) & 0x4000) != 0) {
575 --i;
576 }
577 return i;
578 }
579 } else {
580 d -= 0.5;
581 if (d <= -TWEXP31) {
582 if (d != -TWEXP31 || ((-(p & 0x7FFF) * (q & 0x7FFF)) & 0x4000) == 0) {
583 mp->arith_error = 1;
584 }
585 return -negative_EL_GORDO;
586 } else {
587 int i = (int) d;
588 if (d == (double) i && ((-(p & 0x7FFF) * (q & 0x7FFF)) & 0x4000) != 0) {
589 ++i;
590 }
591 return i;
592 }
593 }
594}
595
596static void mp_scaled_take_scaled(MP mp, mp_number *ret, mp_number *p_orig, mp_number *q_orig)
597{
598 ret->data.val = mp_take_scaled(mp, p_orig->data.val, q_orig->data.val);
599}
600
601
609
610static int mp_make_scaled(MP mp, int p, int q)
611{
612 if (q == 0) {
613 mp_confusion(mp, "division by zero");
614 return 0;
615 } else {
616 double d = TWEXP16 * (double) p / (double) q;
617 if ((p ^ q) >= 0) {
618 d += 0.5;
619 if (d >= TWEXP31) {
620 mp->arith_error = 1;
621 return EL_GORDO;
622 } else {
623 int i = (int) d;
624 if (d == (double) i && (((q > 0 ? -q : q) & 0x7FFF) * (((i & 0x3FFF) << 1) - 1) & 0x800) != 0) {
625 --i;
626 }
627 return i;
628 }
629 } else {
630 d -= 0.5;
631 if (d <= -TWEXP31) {
632 mp->arith_error = 1;
633 return -negative_EL_GORDO;
634 } else {
635 int i = (int) d;
636 if (d == (double) i && (((q > 0 ? q : -q) & 0x7FFF) * (((i & 0x3FFF) << 1) + 1) & 0x800) != 0) {
637 ++i;
638 }
639 return i;
640 }
641 }
642 }
643}
644
645static void mp_scaled_make_scaled(MP mp, mp_number *ret, mp_number *p_orig, mp_number *q_orig)
646{
647 ret->data.val = mp_make_scaled(mp, p_orig->data.val, q_orig->data.val);
648}
649
650
654
655static int mp_round_decimals(MP mp, unsigned char *b, int k)
656{
657 unsigned a = 0;
658 (void) mp;
659 for (int l = k-1; l >= 0; l-- ) {
660 if (l < 16) {
661
662 a = (a + (unsigned) (*(b+l) - '0') * two) / 10;
663 }
664 }
665 return (int) (a + 1)/2;
666}
667
668
673
674static void mp_scaled_wrapup_numeric_token(MP mp, int n, int f)
675{
676 if (n < 32768) {
677 int mod = (n * unity + f);
678 set_cur_mod(mod);
679 if (mod >= fraction_one) {
680 if (internal_value(mp_warning_check_internal).data.val > 0 && (mp->scanner_status != mp_tex_flushing_state)) {
681 char msg[256];
682 snprintf(msg, 256, "Number is too large (%s)", mp_string_scaled(mp,mod));
683 mp_error(
684 mp,
685 msg,
686 "It is at least 4096. Continue and I'll try to cope with that big value;\n"
687 "but it might be dangerous. (Set warningcheck:=0 to suppress this message.)"
688 );
689 }
690 }
691 } else if (mp->scanner_status != mp_tex_flushing_state) {
692 mp_error(
693 mp,
694 "Enormous number has been reduced",
695 "I can\'t handle numbers bigger than 32767.99998; so I've changed your constant\n"
696 "to that maximum amount."
697 );
698 set_cur_mod(EL_GORDO);
699 }
700 set_cur_cmd(mp_numeric_command);
701}
702
703static void mp_scaled_scan_fractional_token(MP mp, int n)
704{
705
706 int f;
707 int k = 0;
708 do {
709 k++;
710 mp->cur_input.loc_field++;
711 } while (mp->char_class[mp->buffer[mp->cur_input.loc_field]] == mp_digit_class);
712 f = mp_round_decimals(mp, (unsigned char *)(mp->buffer+mp->cur_input.loc_field-k), (int) k);
713 if (f == unity) {
714 n++;
715 f = 0;
716 }
717 mp_scaled_wrapup_numeric_token(mp, n, f);
718}
719
720static void mp_scaled_scan_numeric_token(MP mp, int n)
721{
722 while (mp->char_class[mp->buffer[mp->cur_input.loc_field]] == mp_digit_class) {
723 if (n < 32768) {
724 n = 10 * n + mp->buffer[mp->cur_input.loc_field] - '0';
725 }
726 mp->cur_input.loc_field++;
727 }
728 if (! (mp->buffer[mp->cur_input.loc_field] == '.' && mp->char_class[mp->buffer[mp->cur_input.loc_field + 1]] == mp_digit_class)) {
729 mp_scaled_wrapup_numeric_token(mp, n, 0);
730 } else {
731 mp->cur_input.loc_field++;
732 mp_scaled_scan_fractional_token(mp, n);
733 }
734}
735
736
764
765static void mp_scaled_velocity(MP mp, mp_number *ret, mp_number *st, mp_number *ct, mp_number *sf, mp_number *cf, mp_number *t)
766{
767 int acc, num, denom;
768 acc = mp_scaled_aux_take_fraction(mp, st->data.val - (sf->data.val / 16), sf->data.val - (st->data.val / 16));
769 acc = mp_scaled_aux_take_fraction(mp, acc, ct->data.val - cf->data.val);
770 num = fraction_two + mp_scaled_aux_take_fraction(mp, acc, 379625062);
771
774 denom = fraction_three + mp_scaled_aux_take_fraction(mp, ct->data.val, 497706707) + mp_scaled_aux_take_fraction(mp, cf->data.val, 307599661);
775
779 if (t->data.val != unity) {
780
783 num = mp_make_scaled(mp, num, t->data.val);
784 }
785 if (num / 4 >= denom) {
786 ret->data.val = fraction_four;
787 } else {
788 ret->data.val = mp_scaled_aux_make_fraction(mp, num, denom);
789 }
790}
791
792
797
798static int mp_scaled_ab_vs_cd (mp_number *a_orig, mp_number *b_orig, mp_number *c_orig, mp_number *d_orig)
799{
800 int a = a_orig->data.val;
801 int b = b_orig->data.val;
802 int c = c_orig->data.val;
803 int d = d_orig->data.val;
804 if (a < 0) {
805 a = -a;
806 b = -b;
807 }
808 if (c < 0) {
809 c = -c;
810 d = -d;
811 }
812 if (d <= 0) {
813 if (b >= 0) {
814 if ((a == 0 || b == 0) && (c == 0 || d == 0)) {
815 return 0;
816 } else {
817 return 1;
818 }
819 } else if (d == 0) {
820 return a == 0 ? 0 : -1;
821 } else {
822 int q = a;
823 a = c;
824 c = q;
825 q = -b;
826 b = -d;
827 d = q;
828 }
829 } else if (b <= 0) {
830 if (b < 0 && a > 0) {
831 return -1;
832 } else {
833 return c == 0 ? 0 : -1;
834 }
835 }
836 while (1) {
837 int q = a / d;
838 int r = c / b;
839 if (q != r) {
840 return q > r ? 1 : -1;
841 } else {
842 q = a % d;
843 r = c % b;
844 if (r == 0) {
845 return q ? 1 : 0;
846 } else if (q == 0) {
847 return -1;
848 } else {
849 a = b;
850 b = q;
851 c = d;
852 d = r;
853 }
854 }
855 }
856
857}
858
859
883
884static void mp_scaled_crossing_point(MP mp, mp_number *ret, mp_number *aa, mp_number *bb, mp_number *cc)
885{
886 int x, xx, x0, x1, x2;
887 int a = aa->data.val;
888 int b = bb->data.val;
889 int c = cc->data.val;
890 int d;
891 (void) mp;
892 if (a < 0) {
893 ret->data.val = zero_crossing;
894 return;
895 } else if (c >= 0) {
896 if (b >= 0) {
897 if (c > 0) {
898 ret->data.val = no_crossing;
899 } else if ((a == 0) && (b == 0)) {
900 ret->data.val = no_crossing;
901 } else {
902 ret->data.val = one_crossing;
903 }
904 return;
905 } else if (a == 0) {
906 ret->data.val = zero_crossing;
907 return;
908 }
909 } else if (a == 0) {
910 if (b <= 0) {
911 ret->data.val = zero_crossing;
912 return;
913 }
914 }
915
916 d = 1;
917 x0 = a;
918 x1 = a - b;
919 x2 = b - c;
920 do {
921 x = (x1 + x2) / 2;
922 if (x1 - x0 > x0) {
923 x2 = x;
924 x0 += x0;
925 d += d;
926 } else {
927 xx = x1 + x - x0;
928 if (xx > x0) {
929 x2 = x;
930 x0 += x0;
931 d += d;
932 } else {
933 x0 = x0 - xx;
934 if ((x <= x0) && (x + x2 <= x0)) {
935 ret->data.val = no_crossing;
936 return;
937 } else {
938 x1 = x;
939 d = d + d + 1;
940 }
941 }
942 }
943 } while (d < fraction_one);
944 ret->data.val = d - fraction_one;
945}
946
947
951
952static int mp_scaled_round_unscaled(mp_number *x_orig)
953{
954 int x = x_orig->data.val;
955 if (x >= 32768) {
956 return 1 + ((x-32768) / 65536);
957 } else if (x >= -32768) {
958 return 0;
959 } else {
960 return -(1+((-(x+1)-32768) / 65536));
961 }
962}
963static void mp_scaled_floor(mp_number *i)
964{
965 i->data.val = i->data.val & -65536;
966}
967
968static void mp_scaled_fraction_to_round_scaled(mp_number *x_orig)
969{
970 int x = x_orig->data.val;
971 x_orig->type = mp_scaled_type;
972 x_orig->data.val = (x>=2048 ? 1+((x-2048) / 4096) : ( x>=-2048 ? 0 : -(1+((-(x+1)-2048) / 4096))));
973}
974
975
986
987static void mp_scaled_sqrt(MP mp, mp_number *ret, mp_number *x_orig)
988{
989 int x = x_orig->data.val;
990 if (x <= 0) {
991 if (x < 0) {
992 char msg[256];
993 snprintf(msg, 256, "Square root of %s has been replaced by 0", mp_string_scaled(mp, x));
994 mp_error(
995 mp,
996 msg,
997 "Since I don't take square roots of negative numbers, I'm zeroing this one.\n"
998 "Proceed, with fingers crossed."
999 );
1000 }
1001 ret->data.val = 0;
1002 } else {
1003 int k = 23;
1004 int y;
1005 int q = 2;
1006 while (x < fraction_two) {
1007 k--;
1008 x = x + x + x + x;
1009 }
1010 if (x < fraction_four)
1011 y = 0;
1012 else {
1013 x = x - fraction_four;
1014 y = 1;
1015 }
1016 do {
1017
1018 x += x;
1019 y += y;
1020 if (x >= fraction_four) {
1021
1022 x = x - fraction_four;
1023 y++;
1024 };
1025 x += x;
1026 y = y + y - q;
1027 q += q;
1028 if (x >= fraction_four) {
1029 x = x - fraction_four;
1030 y++;
1031 };
1032 if (y > (int) q) {
1033 y -= q;
1034 q += 2;
1035 } else if (y <= 0) {
1036 q -= 2;
1037 y += q;
1038 };
1039 k--;
1040 } while (k != 0);
1041 ret->data.val = (int) (q/2);
1042 }
1043}
1044
1045
1051
1052static void mp_scaled_pyth_add(MP mp, mp_number *ret, mp_number *a_orig, mp_number *b_orig)
1053{
1054 int a = abs(a_orig->data.val);
1055 int b = abs(b_orig->data.val);
1056 if (a < b) {
1057 int r = b;
1058 b = a;
1059 a = r;
1060 }
1061
1062 if (b > 0) {
1063 int big;
1064
1065 if (a < fraction_two) {
1066 big = 0;
1067 } else {
1068 a = a / 4;
1069 b = b / 4;
1070 big = 1;
1071 }
1072
1076 while (1) {
1077 int r = mp_scaled_aux_make_fraction(mp, b, a);
1078 r = mp_scaled_aux_take_fraction(mp, r, r);
1079
1080 if (r == 0) {
1081 break;
1082 } else {
1083 r = mp_scaled_aux_make_fraction(mp, r, fraction_four + r);
1084 a = a + mp_scaled_aux_take_fraction(mp, a + a, r);
1085 b = mp_scaled_aux_take_fraction(mp, b, r);
1086 }
1087 }
1088 if (big) {
1089 if (a < fraction_two) {
1090 a = a + a + a + a;
1091 } else {
1092 mp->arith_error = 1;
1093 a = EL_GORDO;
1094 }
1095 }
1096 }
1097 ret->data.val = a;
1098}
1099
1100
1105
1106static void mp_scaled_pyth_sub(MP mp, mp_number *ret, mp_number *a_orig, mp_number *b_orig)
1107{
1108 int a = abs(a_orig->data.val);
1109 int b = abs(b_orig->data.val);
1110 if (a <= b) {
1111
1112 if (a < b) {
1113 char msg[256];
1114 char *astr = mp_strdup(mp_string_scaled(mp, a));
1115 snprintf(msg, 256, "Pythagorean subtraction %s+-+%s has been replaced by 0", astr, mp_string_scaled(mp, b));
1116 mp_memory_free(astr);
1117 mp_error(
1118 mp,
1119 msg,
1120 "Since I don't take square roots of negative numbers, I'm zeroing this one.\n"
1121 "Proceed, with fingers crossed."
1122 );
1123 }
1124 a = 0;
1125 } else {
1126 int big;
1127
1128 if (a < fraction_four) {
1129 big = 0;
1130 } else {
1131 a = (int) a/2;
1132 b = (int) b/2;
1133 big = 1;
1134 }
1135
1136 while (1) {
1137 int r = mp_scaled_aux_make_fraction(mp, b, a);
1138 r = mp_scaled_aux_take_fraction(mp, r, r);
1139
1140 if (r == 0) {
1141 break;
1142 } else {
1143 r = mp_scaled_aux_make_fraction(mp, r, fraction_four - r);
1144 a = a - mp_scaled_aux_take_fraction(mp, a + a, r);
1145 b = mp_scaled_aux_take_fraction(mp, b, r);
1146 }
1147 }
1148 if (big) {
1149 a *= 2;
1150 }
1151 }
1152 ret->data.val = a;
1153}
1154
1155
1158
1159static void mp_scaled_power_of(MP mp, mp_number *ret, mp_number *a_orig, mp_number *b_orig)
1160{
1161 double p = pow(mp_scaled_to_double(a_orig), mp_scaled_to_double(b_orig));
1162 long r = lround(p * 65536.0);
1163 if (r > 0) {
1164 if (r >= EL_GORDO) {
1165 mp->arith_error = 1;
1166 r = EL_GORDO;
1167 }
1168 } else if (r < 0) {
1169 if (r <= - EL_GORDO) {
1170 mp->arith_error = 1;
1171 r = - EL_GORDO;
1172 }
1173 }
1174 ret->data.val = r;
1175}
1176
1177
1195
1196static void mp_scaled_m_log(MP mp, mp_number *ret, mp_number *x_orig)
1197{
1198 int x = x_orig->data.val;
1199 if (x <= 0) {
1200
1201 char msg[256];
1202 snprintf(msg, 256, "Logarithm of %s has been replaced by 0", mp_string_scaled(mp, x));
1203 mp_error(
1204 mp,
1205 msg,
1206 "Since I don't take logs of non-positive numbers, I'm zeroing this one.\n"
1207 "Proceed, with fingers crossed."
1208 );
1209 ret->data.val = 0;
1210 } else {
1211 int k = 2;
1212 int y = 1302456956 + 4 - 100;
1213 int z = 27595 + 6553600;
1214
1215 while (x < fraction_four) {
1216 x = 2*x;
1217 y -= 93032639;
1218 z -= 48782;
1219 }
1220 y = y + (z / unity);
1221 while (x > fraction_four + 4) {
1222
1226 z = ((x - 1) / two_to_the (k)) + 1;
1227 while (x < fraction_four + z) {
1228 z = (z + 1)/2;
1229 k++;
1230 };
1231 y += mp_m_spec_log[k];
1232 x -= z;
1233 }
1234 ret->data.val = (y / 8);
1235 }
1236}
1237
1238
1244
1245static void mp_scaled_m_exp(MP mp, mp_number *ret, mp_number *x_orig)
1246{
1247 int y, z;
1248 int x = x_orig->data.val;
1249 if (x > 174436200) {
1250
1251 mp->arith_error = 1;
1252 ret->data.val = EL_GORDO;
1253 } else if (x < -197694359) {
1254
1255 ret->data.val = 0;
1256 } else {
1257 if (x <= 0) {
1258 z = -8 * x;
1259 y = 0x100000;
1260 } else {
1261 if (x <= 127919879) {
1262 z = 1023359037 - 8 * x;
1263
1264 } else {
1265
1266 z = 8 * (174436200 - x);
1267 }
1268 y = EL_GORDO;
1269 }
1270
1271 {
1272 int k = 1;
1273 while (z > 0) {
1274 while (z >= mp_m_spec_log[k]) {
1275 z -= mp_m_spec_log[k];
1276 y = y - 1 - ((y - two_to_the(k - 1)) / two_to_the(k));
1277 }
1278 k++;
1279 }
1280 }
1281 if (x <= 127919879) {
1282 ret->data.val = ((y + 8) / 16);
1283 } else {
1284 ret->data.val = y;
1285 }
1286 }
1287}
1288
1289
1306
1307static void mp_scaled_n_arg(MP mp, mp_number *ret, mp_number *x_orig, mp_number *y_orig)
1308{
1309 int octant;
1310 int x = x_orig->data.val;
1311 int y = y_orig->data.val;
1312 if (x >= 0) {
1313 octant = first_octant;
1314 } else {
1315 x = -x;
1316 octant = first_octant + negate_x;
1317 }
1318 if (y < 0) {
1319 y = -y;
1320 octant = octant + negate_y;
1321 }
1322 if (x < y) {
1323 int t = y;
1324 y = x;
1325 x = t;
1326 octant = octant + switch_x_and_y;
1327 }
1328 if (x == 0) {
1329 if (internal_value(mp_default_zero_angle_internal).data.val < 0) {
1330 mp_error(
1331 mp,
1332 "angle(0,0) is taken as zero",
1333 "The 'angle' between two identical points is undefined. I'm zeroing this one.\n"
1334 "Proceed, with fingers crossed."
1335 );
1336 ret->data.val = 0;
1337 } else {
1338 ret->data.val = internal_value(mp_default_zero_angle_internal).data.val;
1339 }
1340 } else {
1341 int z = 0;
1342 ret->type = mp_angle_type;
1343
1344 while (x >= fraction_two) {
1345 x = x/2;
1346 y = y/2;
1347 }
1348 if (y > 0) {
1349 int k= 0;
1350 while (x < fraction_one) {
1351 x += x;
1352 y += y;
1353 };
1354
1355 do {
1356 y += y;
1357 k++;
1358 if (y > x) {
1359 int t = x;
1360 z = z + mp_m_spec_atan[k];
1361 x = x + (y / two_to_the(k + k));
1362 y = y - t;
1363 };
1364 } while (k != 15);
1365 do {
1366 y += y;
1367 k++;
1368 if (y > x) {
1369 z = z + mp_m_spec_atan[k];
1370 y = y - x;
1371 };
1372 } while (k != 26);
1373 }
1374
1375 switch (octant) {
1376 case first_octant: ret->data.val = z; break;
1377 case second_octant: ret->data.val = -z + ninety_deg; break;
1378 case third_octant: ret->data.val = z + ninety_deg; break;
1379 case fourth_octant: ret->data.val = -z + one_eighty_deg; break;
1380 case fifth_octant: ret->data.val = z - one_eighty_deg; break;
1381 case sixth_octant: ret->data.val = -z - ninety_deg; break;
1382 case seventh_octant: ret->data.val = z - ninety_deg; break;
1383 case eighth_octant: ret->data.val = -z; break;
1384 }
1385
1386 }
1387}
1388
1389
1393
1394
1415
1416static void mp_scaled_n_sin_cos(MP mp, mp_number *z_orig, mp_number *n_cos, mp_number *n_sin)
1417{
1418 int k;
1419 int q;
1420 int x, y, t;
1421 int z = z_orig->data.val;
1422 mp_number x_n, y_n, ret;
1423 mp_scaled_allocate_number(mp, &ret, mp_scaled_type);
1424 mp_scaled_allocate_number(mp, &x_n, mp_scaled_type);
1425 mp_scaled_allocate_number(mp, &y_n, mp_scaled_type);
1426 while (z < 0) {
1427 z = z + three_sixty_deg;
1428 }
1429 z = z % three_sixty_deg;
1430
1431 q = z / forty_five_deg;
1432 z = z % forty_five_deg;
1433 x = fraction_one;
1434 y = x;
1435 if (! odd(q)) {
1436 z = forty_five_deg - z;
1437 }
1438
1439 k = 1;
1440 while (z > 0) {
1441 if (z >= mp_m_spec_atan[k]) {
1442 z = z - mp_m_spec_atan[k];
1443 t = x;
1444 x = t + y / two_to_the(k);
1445 y = y - t / two_to_the(k);
1446 }
1447 k++;
1448 }
1449 if (y < 0) {
1450
1451 y = 0;
1452 }
1453
1454 switch (q) {
1455 case 0: break;
1456 case 1: t = x; x = y; y = t; break;
1457 case 2: t = x; x = -y; y = t; break;
1458 case 3: x = -x; break;
1459 case 4: x = -x; y = -y; break;
1460 case 5: t = x; x = -y; y = -t; break;
1461 case 6: t = x; x = y; y = -t; break;
1462 case 7: y = -y; break;
1463 }
1464 x_n.data.val = x;
1465 y_n.data.val = y;
1466 mp_scaled_pyth_add(mp, &ret, &x_n, &y_n);
1467 n_cos->data.val = mp_scaled_aux_make_fraction(mp, x, ret.data.val);
1468 n_sin->data.val = mp_scaled_aux_make_fraction(mp, y, ret.data.val);
1469 mp_scaled_free_number(mp, &ret);
1470 mp_scaled_free_number(mp, &x_n);
1471 mp_scaled_free_number(mp, &y_n);
1472}
1473
1474
1483
1484static void mp_scaled_init_randoms(MP mp, int seed)
1485{
1486 int k = 1;
1487 int j = abs(seed);
1488 while (j >= fraction_one) {
1489 j = j/2;
1490 }
1491 for (int i = 0; i <= 54; i++) {
1492 int jj = k;
1493 k = j - k;
1494 j = jj;
1495 if (k < 0) {
1496 k += fraction_one;
1497 }
1498 mp->randoms[(i * 21) % 55].data.val = j;
1499 }
1500
1501 mp_new_randoms(mp);
1502 mp_new_randoms(mp);
1503 mp_new_randoms(mp);
1504}
1505
1506static void mp_scaled_print(MP mp, mp_number *n)
1507{
1508 mp_print_e_str(mp, mp_string_scaled(mp, n->data.val));
1509}
1510
1511static char *mp_scaled_tostring(MP mp, mp_number *n)
1512{
1513 return mp_string_scaled(mp, n->data.val);
1514}
1515
1516static void mp_scaled_modulo(mp_number *a, mp_number *b)
1517{
1518 a->data.val = a->data.val % b->data.val;
1519}
1520
1521static void mp_next_random(MP mp, mp_number *ret)
1522{
1523 if ( mp->j_random == 0) {
1524 mp_new_randoms(mp);
1525 } else {
1526 mp->j_random = mp->j_random-1;
1527 }
1528 mp_scaled_clone(ret, &(mp->randoms[mp->j_random]));
1529}
1530
1531
1539
1540static void mp_scaled_m_unif_rand(MP mp, mp_number *ret, mp_number *x_orig)
1541{
1542 mp_number x, abs_x, u, y;
1543 mp_scaled_allocate_number(mp, &y, mp_fraction_type);
1544 mp_scaled_allocate_clone(mp, &x, mp_scaled_type, x_orig);
1545 mp_scaled_allocate_abs(mp, &abs_x, mp_scaled_type, &x);
1546 mp_scaled_allocate_number(mp, &u, mp_scaled_type);
1547 mp_next_random(mp, &u);
1548
1549 mp_scaled_take_fraction(mp, &y, &abs_x, &u);
1550 if (mp_scaled_equal(&y, &abs_x)) {
1551
1552 mp_scaled_clone(ret, &((math_data *)mp->math)->md_zero_t);
1553 } else if (mp_scaled_greater(&x, &((math_data *)mp->math)->md_zero_t)) {
1554 mp_scaled_clone(ret, &y);
1555 } else {
1556 mp_scaled_clone(ret, &y);
1557 mp_scaled_negate(ret);
1558 }
1559 mp_scaled_free_number(mp, &y);
1560 mp_scaled_free_number(mp, &abs_x);
1561 mp_scaled_free_number(mp, &x);
1562 mp_scaled_free_number(mp, &u);
1563}
1564
1565
1571
1572static void mp_scaled_m_norm_rand(MP mp, mp_number *ret)
1573{
1574 mp_number abs_x, u, r, la, xa;
1575 mp_scaled_allocate_number(mp, &la, mp_scaled_type);
1576 mp_scaled_allocate_number(mp, &xa, mp_scaled_type);
1577 mp_scaled_allocate_number(mp, &abs_x, mp_scaled_type);
1578 mp_scaled_allocate_number(mp, &u, mp_scaled_type);
1579 mp_scaled_allocate_number(mp, &r, mp_scaled_type);
1580 do {
1581 do {
1582 mp_number v;
1583 mp_scaled_allocate_number(mp, &v, mp_scaled_type);
1584 mp_next_random(mp, &v);
1585 mp_scaled_subtract(&v, &((math_data *)mp->math)->md_fraction_half_t);
1586 mp_scaled_take_fraction(mp, &xa, &((math_data *)mp->math)->md_sqrt_8_e_k, &v);
1587 mp_scaled_free_number(mp, &v);
1588 mp_next_random(mp, &u);
1589 mp_scaled_clone(&abs_x, &xa);
1590 mp_scaled_abs(&abs_x);
1591 } while (! mp_scaled_less(&abs_x, &u));
1592 mp_scaled_make_fraction(mp, &r, &xa, &u);
1593 mp_scaled_clone(&xa, &r);
1594 mp_scaled_m_log(mp, &la, &u);
1595 mp_scaled_set_from_subtraction(&la, &((math_data *)mp->math)->md_twelve_ln_2_k, &la);
1596 } while (mp_scaled_ab_vs_cd(&((math_data *)mp->math)->md_one_k, &la, &xa, &xa) < 0);
1597 mp_scaled_clone(ret, &xa);
1598 mp_scaled_free_number(mp, &r);
1599 mp_scaled_free_number(mp, &abs_x);
1600 mp_scaled_free_number(mp, &la);
1601 mp_scaled_free_number(mp, &xa);
1602 mp_scaled_free_number(mp, &u);
1603}
1604
1605static void mp_scaled_set_precision(MP mp)
1606{
1607 (void) mp;
1608}
1609
1610static void mp_scaled_free_math(MP mp)
1611{
1612 mp_scaled_free_number(mp, &(mp->math->md_epsilon_t));
1613 mp_scaled_free_number(mp, &(mp->math->md_inf_t));
1614 mp_scaled_free_number(mp, &(mp->math->md_negative_inf_t));
1615 mp_scaled_free_number(mp, &(mp->math->md_arc_tol_k));
1616 mp_scaled_free_number(mp, &(mp->math->md_three_sixty_deg_t));
1617 mp_scaled_free_number(mp, &(mp->math->md_one_eighty_deg_t));
1618 mp_scaled_free_number(mp, &(mp->math->md_negative_one_eighty_deg_t));
1619 mp_scaled_free_number(mp, &(mp->math->md_fraction_one_t));
1620 mp_scaled_free_number(mp, &(mp->math->md_fraction_half_t));
1621 mp_scaled_free_number(mp, &(mp->math->md_fraction_three_t));
1622 mp_scaled_free_number(mp, &(mp->math->md_fraction_four_t));
1623 mp_scaled_free_number(mp, &(mp->math->md_zero_t));
1624 mp_scaled_free_number(mp, &(mp->math->md_half_unit_t));
1625 mp_scaled_free_number(mp, &(mp->math->md_three_quarter_unit_t));
1626 mp_scaled_free_number(mp, &(mp->math->md_unity_t));
1627 mp_scaled_free_number(mp, &(mp->math->md_two_t));
1628 mp_scaled_free_number(mp, &(mp->math->md_three_t));
1629 mp_scaled_free_number(mp, &(mp->math->md_one_third_inf_t));
1630 mp_scaled_free_number(mp, &(mp->math->md_warning_limit_t));
1631 mp_scaled_free_number(mp, &(mp->math->md_one_k));
1632 mp_scaled_free_number(mp, &(mp->math->md_sqrt_8_e_k));
1633 mp_scaled_free_number(mp, &(mp->math->md_twelve_ln_2_k));
1634 mp_scaled_free_number(mp, &(mp->math->md_coef_bound_k));
1635 mp_scaled_free_number(mp, &(mp->math->md_coef_bound_minus_1));
1636 mp_scaled_free_number(mp, &(mp->math->md_twelvebits_3));
1637 mp_scaled_free_number(mp, &(mp->math->md_twentysixbits_sqrt2_t));
1638 mp_scaled_free_number(mp, &(mp->math->md_twentyeightbits_d_t));
1639 mp_scaled_free_number(mp, &(mp->math->md_twentysevenbits_sqrt2_d_t));
1640 mp_scaled_free_number(mp, &(mp->math->md_fraction_threshold_t));
1641 mp_scaled_free_number(mp, &(mp->math->md_half_fraction_threshold_t));
1642 mp_scaled_free_number(mp, &(mp->math->md_scaled_threshold_t));
1643 mp_scaled_free_number(mp, &(mp->math->md_half_scaled_threshold_t));
1644 mp_scaled_free_number(mp, &(mp->math->md_near_zero_angle_t));
1645 mp_scaled_free_number(mp, &(mp->math->md_p_over_v_threshold_t));
1646 mp_scaled_free_number(mp, &(mp->math->md_equation_threshold_t));
1647 mp_memory_free(mp->math);
1648}
1649
1650math_data *mp_initialize_scaled_math(MP mp)
1651{
1652 math_data *math = (math_data *) mp_memory_allocate(sizeof(math_data));
1653
1654 math->md_allocate = mp_scaled_allocate_number;
1655 math->md_free = mp_scaled_free_number;
1656 math->md_allocate_clone = mp_scaled_allocate_clone;
1657 math->md_allocate_abs = mp_scaled_allocate_abs;
1658 math->md_allocate_double = mp_scaled_allocate_double;
1659
1660 mp_scaled_allocate_number(mp, &math->md_precision_default, mp_scaled_type);
1661 mp_scaled_allocate_number(mp, &math->md_precision_max, mp_scaled_type);
1662 mp_scaled_allocate_number(mp, &math->md_precision_min, mp_scaled_type);
1663
1664 mp_scaled_allocate_number(mp, &math->md_epsilon_t, mp_scaled_type);
1665 mp_scaled_allocate_number(mp, &math->md_inf_t, mp_scaled_type);
1666 mp_scaled_allocate_number(mp, &math->md_negative_inf_t, mp_scaled_type);
1667 mp_scaled_allocate_number(mp, &math->md_warning_limit_t, mp_scaled_type);
1668 mp_scaled_allocate_number(mp, &math->md_one_third_inf_t, mp_scaled_type);
1669 mp_scaled_allocate_number(mp, &math->md_unity_t, mp_scaled_type);
1670 mp_scaled_allocate_number(mp, &math->md_two_t, mp_scaled_type);
1671 mp_scaled_allocate_number(mp, &math->md_three_t, mp_scaled_type);
1672 mp_scaled_allocate_number(mp, &math->md_half_unit_t, mp_scaled_type);
1673 mp_scaled_allocate_number(mp, &math->md_three_quarter_unit_t, mp_scaled_type);
1674 mp_scaled_allocate_number(mp, &math->md_zero_t, mp_scaled_type);
1675
1676 mp_scaled_allocate_number(mp, &math->md_arc_tol_k, mp_fraction_type);
1677 mp_scaled_allocate_number(mp, &math->md_fraction_one_t, mp_fraction_type);
1678 mp_scaled_allocate_number(mp, &math->md_fraction_half_t, mp_fraction_type);
1679 mp_scaled_allocate_number(mp, &math->md_fraction_three_t, mp_fraction_type);
1680 mp_scaled_allocate_number(mp, &math->md_fraction_four_t, mp_fraction_type);
1681
1682 mp_scaled_allocate_number(mp, &math->md_three_sixty_deg_t, mp_angle_type);
1683 mp_scaled_allocate_number(mp, &math->md_one_eighty_deg_t, mp_angle_type);
1684 mp_scaled_allocate_number(mp, &math->md_negative_one_eighty_deg_t, mp_angle_type);
1685
1686 mp_scaled_allocate_number(mp, &math->md_one_k, mp_scaled_type);
1687 mp_scaled_allocate_number(mp, &math->md_sqrt_8_e_k, mp_scaled_type);
1688 mp_scaled_allocate_number(mp, &math->md_twelve_ln_2_k, mp_fraction_type);
1689 mp_scaled_allocate_number(mp, &math->md_coef_bound_k, mp_fraction_type);
1690 mp_scaled_allocate_number(mp, &math->md_coef_bound_minus_1, mp_fraction_type);
1691 mp_scaled_allocate_number(mp, &math->md_twelvebits_3, mp_scaled_type);
1692 mp_scaled_allocate_number(mp, &math->md_twentysixbits_sqrt2_t, mp_fraction_type);
1693 mp_scaled_allocate_number(mp, &math->md_twentyeightbits_d_t, mp_fraction_type);
1694 mp_scaled_allocate_number(mp, &math->md_twentysevenbits_sqrt2_d_t, mp_fraction_type);
1695
1696 mp_scaled_allocate_number(mp, &math->md_fraction_threshold_t, mp_fraction_type);
1697 mp_scaled_allocate_number(mp, &math->md_half_fraction_threshold_t, mp_fraction_type);
1698 mp_scaled_allocate_number(mp, &math->md_scaled_threshold_t, mp_scaled_type);
1699 mp_scaled_allocate_number(mp, &math->md_half_scaled_threshold_t, mp_scaled_type);
1700 mp_scaled_allocate_number(mp, &math->md_near_zero_angle_t, mp_angle_type);
1701 mp_scaled_allocate_number(mp, &math->md_p_over_v_threshold_t, mp_fraction_type);
1702 mp_scaled_allocate_number(mp, &math->md_equation_threshold_t, mp_scaled_type);
1703
1704 math->md_precision_default.data.val = unity * 10;
1705 math->md_precision_max.data.val = unity * 10;
1706 math->md_precision_min.data.val = unity * 10;
1707 math->md_epsilon_t.data.val = 1;
1708 math->md_inf_t.data.val = EL_GORDO;
1709 math->md_negative_inf_t.data.val = negative_EL_GORDO;
1710 math->md_one_third_inf_t.data.val = one_third_EL_GORDO;
1711 math->md_warning_limit_t.data.val = fraction_one;
1712 math->md_unity_t.data.val = unity;
1713 math->md_two_t.data.val = two;
1714 math->md_three_t.data.val = three;
1715 math->md_half_unit_t.data.val = half_unit;
1716 math->md_three_quarter_unit_t.data.val = three_quarter_unit;
1717 math->md_arc_tol_k.data.val = (unity/4096);
1718 math->md_fraction_one_t.data.val = fraction_one;
1719 math->md_fraction_half_t.data.val = fraction_half;
1720 math->md_fraction_three_t.data.val = fraction_three;
1721 math->md_fraction_four_t.data.val = fraction_four;
1722 math->md_three_sixty_deg_t.data.val = three_sixty_deg;
1723 math->md_one_eighty_deg_t.data.val = one_eighty_deg;
1724 math->md_negative_one_eighty_deg_t.data.val = negative_one_eighty_deg;
1725 math->md_one_k.data.val = 1024;
1726 math->md_sqrt_8_e_k.data.val = 112429;
1727 math->md_twelve_ln_2_k.data.val = 139548960;
1728 math->md_coef_bound_k.data.val = coef_bound;
1729 math->md_coef_bound_minus_1.data.val = coef_bound - 1;
1730 math->md_twelvebits_3.data.val = 1365;
1731 math->md_twentysixbits_sqrt2_t.data.val = 94906266;
1732 math->md_twentyeightbits_d_t.data.val = 35596755;
1733 math->md_twentysevenbits_sqrt2_d_t.data.val = 25170707;
1734 math->md_fraction_threshold_t.data.val = fraction_threshold;
1735 math->md_half_fraction_threshold_t.data.val = half_fraction_threshold;
1736 math->md_scaled_threshold_t.data.val = scaled_threshold;
1737 math->md_half_scaled_threshold_t.data.val = half_scaled_threshold;
1738 math->md_near_zero_angle_t.data.val = near_zero_angle;
1739 math->md_p_over_v_threshold_t.data.val = p_over_v_threshold;
1740 math->md_equation_threshold_t.data.val = equation_threshold;
1741
1742 math->md_from_int = mp_scaled_set_from_int;
1743 math->md_from_boolean = mp_scaled_set_from_boolean;
1744 math->md_from_scaled = mp_scaled_set_from_scaled;
1745 math->md_from_double = mp_scaled_set_from_double;
1746 math->md_from_addition = mp_scaled_set_from_addition;
1747 math->md_half_from_addition = mp_scaled_set_half_from_addition;
1748 math->md_from_subtraction = mp_scaled_set_from_subtraction;
1749 math->md_half_from_subtraction = mp_scaled_set_half_from_subtraction;
1750 math->md_from_of_the_way = mp_scaled_set_from_of_the_way;
1751 math->md_from_div = mp_scaled_set_from_div;
1752 math->md_from_mul = mp_scaled_set_from_mul;
1753 math->md_from_int_div = mp_scaled_set_from_int_div;
1754 math->md_from_int_mul = mp_scaled_set_from_int_mul;
1755 math->md_negate = mp_scaled_negate;
1756 math->md_add = mp_scaled_add;
1757 math->md_subtract = mp_scaled_subtract;
1758 math->md_half = mp_scaled_half;
1759 math->md_do_double = mp_scaled_double;
1760 math->md_abs = mp_scaled_abs;
1761 math->md_clone = mp_scaled_clone;
1762 math->md_negated_clone = mp_scaled_negated_clone;
1763 math->md_abs_clone = mp_scaled_abs_clone;
1764 math->md_swap = mp_scaled_swap;
1765 math->md_add_scaled = mp_scaled_add_scaled;
1766 math->md_multiply_int = mp_scaled_multiply_int;
1767 math->md_divide_int = mp_scaled_divide_int;
1768 math->md_to_int = mp_scaled_to_int;
1769 math->md_to_boolean = mp_scaled_to_boolean;
1770 math->md_to_scaled = mp_scaled_to_scaled;
1771 math->md_to_double = mp_scaled_to_double;
1772 math->md_odd = mp_scaled_odd;
1773 math->md_equal = mp_scaled_equal;
1774 math->md_less = mp_scaled_less;
1775 math->md_greater = mp_scaled_greater;
1776 math->md_non_equal_abs = mp_scaled_non_equal_abs;
1777 math->md_round_unscaled = mp_scaled_round_unscaled;
1778 math->md_floor_scaled = mp_scaled_floor;
1779 math->md_fraction_to_round_scaled = mp_scaled_fraction_to_round_scaled;
1780 math->md_make_scaled = mp_scaled_make_scaled;
1781 math->md_make_fraction = mp_scaled_make_fraction;
1782 math->md_take_fraction = mp_scaled_take_fraction;
1783 math->md_take_scaled = mp_scaled_take_scaled;
1784 math->md_velocity = mp_scaled_velocity;
1785 math->md_n_arg = mp_scaled_n_arg;
1786 math->md_m_log = mp_scaled_m_log;
1787 math->md_m_exp = mp_scaled_m_exp;
1788 math->md_m_unif_rand = mp_scaled_m_unif_rand;
1789 math->md_m_norm_rand = mp_scaled_m_norm_rand;
1790 math->md_pyth_add = mp_scaled_pyth_add;
1791 math->md_pyth_sub = mp_scaled_pyth_sub;
1792 math->md_power_of = mp_scaled_power_of;
1793 math->md_fraction_to_scaled = mp_scaled_fraction_to_scaled;
1794 math->md_scaled_to_fraction = mp_scaled_scaled_to_fraction;
1795 math->md_scaled_to_angle = mp_scaled_scaled_to_angle;
1796 math->md_angle_to_scaled = mp_scaled_angle_to_scaled;
1797 math->md_init_randoms = mp_scaled_init_randoms;
1798 math->md_sin_cos = mp_scaled_n_sin_cos;
1799 math->md_slow_add = mp_scaled_slow_add;
1800 math->md_sqrt = mp_scaled_sqrt;
1801 math->md_print = mp_scaled_print;
1802 math->md_tostring = mp_scaled_tostring;
1803 math->md_modulo = mp_scaled_modulo;
1804 math->md_ab_vs_cd = mp_scaled_ab_vs_cd;
1805 math->md_crossing_point = mp_scaled_crossing_point;
1806 math->md_scan_numeric = mp_scaled_scan_numeric_token;
1807 math->md_scan_fractional = mp_scaled_scan_fractional_token;
1808
1809 math->md_free_math = mp_scaled_free_math;
1810 math->md_set_precision = mp_scaled_set_precision;
1811 return math;
1812}
1813 |