Mercurial > hg > xemacs-beta
comparison src/number-gmp.c @ 1983:9c872f33ecbe
[xemacs-hg @ 2004-04-05 22:49:31 by james]
Add bignum, ratio, and bigfloat support.
author | james |
---|---|
date | Mon, 05 Apr 2004 22:50:11 +0000 |
parents | |
children | 4e6a63799f08 |
comparison
equal
deleted
inserted
replaced
1982:a748951fd4fb | 1983:9c872f33ecbe |
---|---|
1 /* Numeric types for XEmacs using the GNU MP library. | |
2 Copyright (C) 2004 Jerry James. | |
3 | |
4 This file is part of XEmacs. | |
5 | |
6 XEmacs is free software; you can redistribute it and/or modify it | |
7 under the terms of the GNU General Public License as published by the | |
8 Free Software Foundation; either version 2, or (at your option) any | |
9 later version. | |
10 | |
11 XEmacs is distributed in the hope that it will be useful, but WITHOUT | |
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
14 for more details. | |
15 | |
16 You should have received a copy of the GNU General Public License | |
17 along with XEmacs; see the file COPYING. If not, write to | |
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, | |
19 Boston, MA 02111-1307, USA. */ | |
20 | |
21 /* Synched up with: Not in FSF. */ | |
22 | |
23 #include <config.h> | |
24 #include <limits.h> | |
25 #include <math.h> | |
26 #include "lisp.h" | |
27 | |
28 static mpf_t float_print_min, float_print_max; | |
29 gmp_randstate_t random_state; | |
30 | |
31 CIbyte * | |
32 bigfloat_to_string(mpf_t f, int base) | |
33 { | |
34 mp_exp_t expt; | |
35 CIbyte *str = mpf_get_str (NULL, &expt, base, 0, f); | |
36 const int sign = mpf_sgn (f); | |
37 const int neg = (sign < 0) ? 1 : 0; | |
38 int len = strlen (str) + 1; /* Count the null terminator */ | |
39 | |
40 if (sign == 0 || (mpf_cmp (float_print_min, f) <= 0 && | |
41 mpf_cmp (f, float_print_max) <= 0)) | |
42 { | |
43 /* Move digits down to insert a radix point */ | |
44 if (expt <= 0) | |
45 { | |
46 /* We need room for a radix point and leading zeroes */ | |
47 const int space = -expt + 2; | |
48 XREALLOC_ARRAY (str, CIbyte, len + space); | |
49 memmove (&str[space + neg], &str[neg], len - neg); | |
50 memset (&str[neg], '0', space); | |
51 str[neg + 1] = '.'; | |
52 len += space; | |
53 } | |
54 else | |
55 { | |
56 /* We just need room for a radix point */ | |
57 XREALLOC_ARRAY (str, CIbyte, len + 1); | |
58 memmove (&str[expt + neg + 1], &str[expt + neg], len - (expt + neg)); | |
59 str[expt + neg] = '.'; | |
60 len++; | |
61 } | |
62 } | |
63 else | |
64 { | |
65 /* Computerized scientific notation */ | |
66 /* We need room for a radix point, format identifier, and exponent */ | |
67 const int space = (expt < 0) | |
68 ? (int)(log (-expt) / log (base)) + 3 | |
69 : (int)(log (expt) / log (base)) + 2; | |
70 XREALLOC_ARRAY (str, CIbyte, len + space); | |
71 memmove (&str[neg + 2], &str[neg + 1], len - neg); | |
72 str[len + 1] = 'l'; | |
73 sprintf (&str[len + 2], "%ld", expt); | |
74 } | |
75 return str; | |
76 } | |
77 | |
78 /* We need the next two functions since GNU MP insists on giving us an extra | |
79 parameter. */ | |
80 static void *gmp_realloc (void *ptr, size_t old_size /* unused */, | |
81 size_t new_size) | |
82 { | |
83 return xrealloc (ptr, new_size); | |
84 } | |
85 | |
86 static void gmp_free (void *ptr, size_t size /* unused */) | |
87 { | |
88 xfree (ptr, void *); | |
89 } | |
90 | |
91 void | |
92 init_number_gmp () | |
93 { | |
94 mp_set_memory_functions ((void *(*) (size_t))xmalloc, gmp_realloc, gmp_free); | |
95 | |
96 /* The smallest number that is printed without exponents */ | |
97 mpf_init_set_d (float_print_min, 0.001); | |
98 | |
99 /* The largest number that is printed without exponents */ | |
100 mpf_init_set_ui (float_print_max, 10000000UL); | |
101 | |
102 /* Prepare the bignum/bigfloat random number generator */ | |
103 gmp_randinit_default (random_state); | |
104 gmp_randseed_ui (random_state, qxe_getpid () + time (NULL)); | |
105 } |