Mercurial > hg > xemacs-beta
annotate src/number-gmp.c @ 5781:0853e1ec8529
Use alloca_{rawbytes,ibytes} in #'copy-file, #'insert-file-contents-internal
src/ChangeLog addition:
2014-01-20 Aidan Kehoe <kehoea@parhasard.net>
* fileio.c (Fcopy_file, Finsert_file_contents_internal):
Use alloca_{rawbytes,ibytes} here instead of the implicit alloca
on the stack; doesn't change where the buffers are allocated for
these two functions, but does mean that decisions about alloca
vs. malloc based on buffer size are made in the same place
(ultimately, the ALLOCA() macro).
author | Aidan Kehoe <kehoea@parhasard.net> |
---|---|
date | Mon, 20 Jan 2014 17:53:07 +0000 |
parents | a2912073be85 |
children |
rev | line source |
---|---|
5739
a2912073be85
Support bignums with MPIR. Add documentation on the bignum, ratio,
Jerry James <james@xemacs.org>
parents:
5736
diff
changeset
|
1 /* Numeric types for XEmacs using the GMP or MPIR library. |
a2912073be85
Support bignums with MPIR. Add documentation on the bignum, ratio,
Jerry James <james@xemacs.org>
parents:
5736
diff
changeset
|
2 Copyright (C) 2004,2013 Jerry James. |
1983 | 3 |
4 This file is part of XEmacs. | |
5 | |
5405
2aa9cd456ae7
Move src/ to GPLv3.
Mike Sperber <sperber@deinprogramm.de>
parents:
5231
diff
changeset
|
6 XEmacs is free software: you can redistribute it and/or modify it |
1983 | 7 under the terms of the GNU General Public License as published by the |
5405
2aa9cd456ae7
Move src/ to GPLv3.
Mike Sperber <sperber@deinprogramm.de>
parents:
5231
diff
changeset
|
8 Free Software Foundation, either version 3 of the License, or (at your |
2aa9cd456ae7
Move src/ to GPLv3.
Mike Sperber <sperber@deinprogramm.de>
parents:
5231
diff
changeset
|
9 option) any later version. |
1983 | 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 | |
5405
2aa9cd456ae7
Move src/ to GPLv3.
Mike Sperber <sperber@deinprogramm.de>
parents:
5231
diff
changeset
|
17 along with XEmacs. If not, see <http://www.gnu.org/licenses/>. */ |
1983 | 18 |
19 /* Synched up with: Not in FSF. */ | |
20 | |
21 #include <config.h> | |
22 #include <limits.h> | |
23 #include <math.h> | |
24 #include "lisp.h" | |
1995 | 25 #include "sysproc.h" /* For qxe_getpid */ |
1983 | 26 |
4612
313c2cc696b9
Fix the broken bigfloat-to-string conversion function.
Jerry James <james@xemacs.org>
parents:
2956
diff
changeset
|
27 static mp_exp_t float_print_min, float_print_max; |
1983 | 28 gmp_randstate_t random_state; |
29 | |
5736
3192994c49ca
Convert C (un)signed long long values to bignums properly.
Jerry James <james@xemacs.org>
parents:
5405
diff
changeset
|
30 long long |
3192994c49ca
Convert C (un)signed long long values to bignums properly.
Jerry James <james@xemacs.org>
parents:
5405
diff
changeset
|
31 bignum_to_llong (const bignum b) |
3192994c49ca
Convert C (un)signed long long values to bignums properly.
Jerry James <james@xemacs.org>
parents:
5405
diff
changeset
|
32 { |
3192994c49ca
Convert C (un)signed long long values to bignums properly.
Jerry James <james@xemacs.org>
parents:
5405
diff
changeset
|
33 long long l; |
3192994c49ca
Convert C (un)signed long long values to bignums properly.
Jerry James <james@xemacs.org>
parents:
5405
diff
changeset
|
34 |
3192994c49ca
Convert C (un)signed long long values to bignums properly.
Jerry James <james@xemacs.org>
parents:
5405
diff
changeset
|
35 mpz_export (&l, NULL, 1, sizeof (l), 0, 0U, b); |
3192994c49ca
Convert C (un)signed long long values to bignums properly.
Jerry James <james@xemacs.org>
parents:
5405
diff
changeset
|
36 return (mpz_sgn (b) < 0) ? -l : l; |
3192994c49ca
Convert C (un)signed long long values to bignums properly.
Jerry James <james@xemacs.org>
parents:
5405
diff
changeset
|
37 } |
3192994c49ca
Convert C (un)signed long long values to bignums properly.
Jerry James <james@xemacs.org>
parents:
5405
diff
changeset
|
38 |
3192994c49ca
Convert C (un)signed long long values to bignums properly.
Jerry James <james@xemacs.org>
parents:
5405
diff
changeset
|
39 unsigned long long |
3192994c49ca
Convert C (un)signed long long values to bignums properly.
Jerry James <james@xemacs.org>
parents:
5405
diff
changeset
|
40 bignum_to_ullong (const bignum b) |
3192994c49ca
Convert C (un)signed long long values to bignums properly.
Jerry James <james@xemacs.org>
parents:
5405
diff
changeset
|
41 { |
3192994c49ca
Convert C (un)signed long long values to bignums properly.
Jerry James <james@xemacs.org>
parents:
5405
diff
changeset
|
42 unsigned long long l; |
3192994c49ca
Convert C (un)signed long long values to bignums properly.
Jerry James <james@xemacs.org>
parents:
5405
diff
changeset
|
43 |
3192994c49ca
Convert C (un)signed long long values to bignums properly.
Jerry James <james@xemacs.org>
parents:
5405
diff
changeset
|
44 mpz_export (&l, NULL, 1, sizeof (l), 0, 0U, b); |
3192994c49ca
Convert C (un)signed long long values to bignums properly.
Jerry James <james@xemacs.org>
parents:
5405
diff
changeset
|
45 return l; |
3192994c49ca
Convert C (un)signed long long values to bignums properly.
Jerry James <james@xemacs.org>
parents:
5405
diff
changeset
|
46 } |
3192994c49ca
Convert C (un)signed long long values to bignums properly.
Jerry James <james@xemacs.org>
parents:
5405
diff
changeset
|
47 |
3192994c49ca
Convert C (un)signed long long values to bignums properly.
Jerry James <james@xemacs.org>
parents:
5405
diff
changeset
|
48 void |
3192994c49ca
Convert C (un)signed long long values to bignums properly.
Jerry James <james@xemacs.org>
parents:
5405
diff
changeset
|
49 bignum_set_llong (bignum b, long long l) |
3192994c49ca
Convert C (un)signed long long values to bignums properly.
Jerry James <james@xemacs.org>
parents:
5405
diff
changeset
|
50 { |
3192994c49ca
Convert C (un)signed long long values to bignums properly.
Jerry James <james@xemacs.org>
parents:
5405
diff
changeset
|
51 if (l < 0LL) |
3192994c49ca
Convert C (un)signed long long values to bignums properly.
Jerry James <james@xemacs.org>
parents:
5405
diff
changeset
|
52 { |
3192994c49ca
Convert C (un)signed long long values to bignums properly.
Jerry James <james@xemacs.org>
parents:
5405
diff
changeset
|
53 /* This even works for LLONG_MIN. Try it! */ |
3192994c49ca
Convert C (un)signed long long values to bignums properly.
Jerry James <james@xemacs.org>
parents:
5405
diff
changeset
|
54 l = -l; |
3192994c49ca
Convert C (un)signed long long values to bignums properly.
Jerry James <james@xemacs.org>
parents:
5405
diff
changeset
|
55 mpz_import (b, 1U, 1, sizeof (l), 0, 0U, &l); |
3192994c49ca
Convert C (un)signed long long values to bignums properly.
Jerry James <james@xemacs.org>
parents:
5405
diff
changeset
|
56 mpz_neg (b, b); |
3192994c49ca
Convert C (un)signed long long values to bignums properly.
Jerry James <james@xemacs.org>
parents:
5405
diff
changeset
|
57 } |
3192994c49ca
Convert C (un)signed long long values to bignums properly.
Jerry James <james@xemacs.org>
parents:
5405
diff
changeset
|
58 else |
3192994c49ca
Convert C (un)signed long long values to bignums properly.
Jerry James <james@xemacs.org>
parents:
5405
diff
changeset
|
59 { |
3192994c49ca
Convert C (un)signed long long values to bignums properly.
Jerry James <james@xemacs.org>
parents:
5405
diff
changeset
|
60 mpz_import (b, 1U, 1, sizeof (l), 0, 0U, &l); |
3192994c49ca
Convert C (un)signed long long values to bignums properly.
Jerry James <james@xemacs.org>
parents:
5405
diff
changeset
|
61 } |
3192994c49ca
Convert C (un)signed long long values to bignums properly.
Jerry James <james@xemacs.org>
parents:
5405
diff
changeset
|
62 } |
3192994c49ca
Convert C (un)signed long long values to bignums properly.
Jerry James <james@xemacs.org>
parents:
5405
diff
changeset
|
63 |
1983 | 64 CIbyte * |
5736
3192994c49ca
Convert C (un)signed long long values to bignums properly.
Jerry James <james@xemacs.org>
parents:
5405
diff
changeset
|
65 bigfloat_to_string (mpf_t f, int base) |
1983 | 66 { |
67 mp_exp_t expt; | |
68 CIbyte *str = mpf_get_str (NULL, &expt, base, 0, f); | |
69 const int sign = mpf_sgn (f); | |
70 const int neg = (sign < 0) ? 1 : 0; | |
71 int len = strlen (str) + 1; /* Count the null terminator */ | |
72 | |
4612
313c2cc696b9
Fix the broken bigfloat-to-string conversion function.
Jerry James <james@xemacs.org>
parents:
2956
diff
changeset
|
73 if (sign == 0) |
313c2cc696b9
Fix the broken bigfloat-to-string conversion function.
Jerry James <james@xemacs.org>
parents:
2956
diff
changeset
|
74 { |
313c2cc696b9
Fix the broken bigfloat-to-string conversion function.
Jerry James <james@xemacs.org>
parents:
2956
diff
changeset
|
75 XREALLOC_ARRAY (str, CIbyte, 4); |
313c2cc696b9
Fix the broken bigfloat-to-string conversion function.
Jerry James <james@xemacs.org>
parents:
2956
diff
changeset
|
76 strncpy (str, "0.0", 4); |
313c2cc696b9
Fix the broken bigfloat-to-string conversion function.
Jerry James <james@xemacs.org>
parents:
2956
diff
changeset
|
77 } |
313c2cc696b9
Fix the broken bigfloat-to-string conversion function.
Jerry James <james@xemacs.org>
parents:
2956
diff
changeset
|
78 else if (float_print_min <= expt && expt <= float_print_max) |
1983 | 79 { |
4612
313c2cc696b9
Fix the broken bigfloat-to-string conversion function.
Jerry James <james@xemacs.org>
parents:
2956
diff
changeset
|
80 if (expt < 0) |
313c2cc696b9
Fix the broken bigfloat-to-string conversion function.
Jerry James <james@xemacs.org>
parents:
2956
diff
changeset
|
81 { |
313c2cc696b9
Fix the broken bigfloat-to-string conversion function.
Jerry James <james@xemacs.org>
parents:
2956
diff
changeset
|
82 /* We need room for a radix point and leading zeroes */ |
313c2cc696b9
Fix the broken bigfloat-to-string conversion function.
Jerry James <james@xemacs.org>
parents:
2956
diff
changeset
|
83 const int space = -expt + 2; |
313c2cc696b9
Fix the broken bigfloat-to-string conversion function.
Jerry James <james@xemacs.org>
parents:
2956
diff
changeset
|
84 XREALLOC_ARRAY (str, CIbyte, len + space); |
313c2cc696b9
Fix the broken bigfloat-to-string conversion function.
Jerry James <james@xemacs.org>
parents:
2956
diff
changeset
|
85 memmove (&str[space + neg], &str[neg], len - neg); |
313c2cc696b9
Fix the broken bigfloat-to-string conversion function.
Jerry James <james@xemacs.org>
parents:
2956
diff
changeset
|
86 memset (&str[neg], '0', space); |
313c2cc696b9
Fix the broken bigfloat-to-string conversion function.
Jerry James <james@xemacs.org>
parents:
2956
diff
changeset
|
87 str[neg + 1] = '.'; |
313c2cc696b9
Fix the broken bigfloat-to-string conversion function.
Jerry James <james@xemacs.org>
parents:
2956
diff
changeset
|
88 } |
313c2cc696b9
Fix the broken bigfloat-to-string conversion function.
Jerry James <james@xemacs.org>
parents:
2956
diff
changeset
|
89 else if (len <= expt + neg + 1) |
313c2cc696b9
Fix the broken bigfloat-to-string conversion function.
Jerry James <james@xemacs.org>
parents:
2956
diff
changeset
|
90 { |
313c2cc696b9
Fix the broken bigfloat-to-string conversion function.
Jerry James <james@xemacs.org>
parents:
2956
diff
changeset
|
91 /* We need room for a radix point and trailing zeroes */ |
313c2cc696b9
Fix the broken bigfloat-to-string conversion function.
Jerry James <james@xemacs.org>
parents:
2956
diff
changeset
|
92 XREALLOC_ARRAY (str, CIbyte, expt + neg + 3); |
313c2cc696b9
Fix the broken bigfloat-to-string conversion function.
Jerry James <james@xemacs.org>
parents:
2956
diff
changeset
|
93 memset (&str[len - 1], '0', expt + neg + 3 - len); |
313c2cc696b9
Fix the broken bigfloat-to-string conversion function.
Jerry James <james@xemacs.org>
parents:
2956
diff
changeset
|
94 str[expt + neg] = '.'; |
313c2cc696b9
Fix the broken bigfloat-to-string conversion function.
Jerry James <james@xemacs.org>
parents:
2956
diff
changeset
|
95 str[expt + neg + 2] = '\0'; |
313c2cc696b9
Fix the broken bigfloat-to-string conversion function.
Jerry James <james@xemacs.org>
parents:
2956
diff
changeset
|
96 } |
1983 | 97 else |
4612
313c2cc696b9
Fix the broken bigfloat-to-string conversion function.
Jerry James <james@xemacs.org>
parents:
2956
diff
changeset
|
98 { |
313c2cc696b9
Fix the broken bigfloat-to-string conversion function.
Jerry James <james@xemacs.org>
parents:
2956
diff
changeset
|
99 /* We just need room for a radix point */ |
313c2cc696b9
Fix the broken bigfloat-to-string conversion function.
Jerry James <james@xemacs.org>
parents:
2956
diff
changeset
|
100 XREALLOC_ARRAY (str, CIbyte, len + 1); |
313c2cc696b9
Fix the broken bigfloat-to-string conversion function.
Jerry James <james@xemacs.org>
parents:
2956
diff
changeset
|
101 memmove (&str[expt + neg + 1], &str[expt + neg], len - (expt + neg)); |
313c2cc696b9
Fix the broken bigfloat-to-string conversion function.
Jerry James <james@xemacs.org>
parents:
2956
diff
changeset
|
102 str[expt + neg] = '.'; |
313c2cc696b9
Fix the broken bigfloat-to-string conversion function.
Jerry James <james@xemacs.org>
parents:
2956
diff
changeset
|
103 } |
1983 | 104 } |
105 else | |
106 { | |
4612
313c2cc696b9
Fix the broken bigfloat-to-string conversion function.
Jerry James <james@xemacs.org>
parents:
2956
diff
changeset
|
107 /* Computerized scientific notation: We need room for a possible radix |
313c2cc696b9
Fix the broken bigfloat-to-string conversion function.
Jerry James <james@xemacs.org>
parents:
2956
diff
changeset
|
108 point, format identifier, and exponent */ |
313c2cc696b9
Fix the broken bigfloat-to-string conversion function.
Jerry James <james@xemacs.org>
parents:
2956
diff
changeset
|
109 /* GMP's idea of the exponent is 1 greater than scientific notation's */ |
313c2cc696b9
Fix the broken bigfloat-to-string conversion function.
Jerry James <james@xemacs.org>
parents:
2956
diff
changeset
|
110 expt--; |
5016
2ade80e8c640
enable more warnings and fix them
Ben Wing <ben@xemacs.org>
parents:
4976
diff
changeset
|
111 { |
2ade80e8c640
enable more warnings and fix them
Ben Wing <ben@xemacs.org>
parents:
4976
diff
changeset
|
112 const int point = (len == neg + 2) ? 0 : 1; |
2ade80e8c640
enable more warnings and fix them
Ben Wing <ben@xemacs.org>
parents:
4976
diff
changeset
|
113 const int exponent = (expt < 0) |
2ade80e8c640
enable more warnings and fix them
Ben Wing <ben@xemacs.org>
parents:
4976
diff
changeset
|
114 ? (int)(log ((double) (-expt)) / log ((double) base)) + 3 |
2ade80e8c640
enable more warnings and fix them
Ben Wing <ben@xemacs.org>
parents:
4976
diff
changeset
|
115 : (int)(log ((double) expt) / log ((double) base)) + 2; |
2ade80e8c640
enable more warnings and fix them
Ben Wing <ben@xemacs.org>
parents:
4976
diff
changeset
|
116 const int space = point + exponent; |
2ade80e8c640
enable more warnings and fix them
Ben Wing <ben@xemacs.org>
parents:
4976
diff
changeset
|
117 XREALLOC_ARRAY (str, CIbyte, len + space); |
2ade80e8c640
enable more warnings and fix them
Ben Wing <ben@xemacs.org>
parents:
4976
diff
changeset
|
118 if (point > 0) |
2ade80e8c640
enable more warnings and fix them
Ben Wing <ben@xemacs.org>
parents:
4976
diff
changeset
|
119 { |
2ade80e8c640
enable more warnings and fix them
Ben Wing <ben@xemacs.org>
parents:
4976
diff
changeset
|
120 memmove (&str[neg + 2], &str[neg + 1], len - neg); |
2ade80e8c640
enable more warnings and fix them
Ben Wing <ben@xemacs.org>
parents:
4976
diff
changeset
|
121 str[neg + 1] = '.'; |
2ade80e8c640
enable more warnings and fix them
Ben Wing <ben@xemacs.org>
parents:
4976
diff
changeset
|
122 } |
2ade80e8c640
enable more warnings and fix them
Ben Wing <ben@xemacs.org>
parents:
4976
diff
changeset
|
123 sprintf (&str[len + point - 1], "E%ld", expt); |
2ade80e8c640
enable more warnings and fix them
Ben Wing <ben@xemacs.org>
parents:
4976
diff
changeset
|
124 } |
1983 | 125 } |
126 return str; | |
127 } | |
128 | |
129 /* We need the next two functions since GNU MP insists on giving us an extra | |
130 parameter. */ | |
5736
3192994c49ca
Convert C (un)signed long long values to bignums properly.
Jerry James <james@xemacs.org>
parents:
5405
diff
changeset
|
131 static void * |
3192994c49ca
Convert C (un)signed long long values to bignums properly.
Jerry James <james@xemacs.org>
parents:
5405
diff
changeset
|
132 gmp_realloc (void *ptr, size_t UNUSED (old_size), size_t new_size) |
1983 | 133 { |
134 return xrealloc (ptr, new_size); | |
135 } | |
136 | |
5736
3192994c49ca
Convert C (un)signed long long values to bignums properly.
Jerry James <james@xemacs.org>
parents:
5405
diff
changeset
|
137 static void |
3192994c49ca
Convert C (un)signed long long values to bignums properly.
Jerry James <james@xemacs.org>
parents:
5405
diff
changeset
|
138 gmp_free (void *ptr, size_t UNUSED (size)) |
1983 | 139 { |
4976
16112448d484
Rename xfree(FOO, TYPE) -> xfree(FOO)
Ben Wing <ben@xemacs.org>
parents:
4802
diff
changeset
|
140 xfree (ptr); |
1983 | 141 } |
142 | |
143 void | |
5739
a2912073be85
Support bignums with MPIR. Add documentation on the bignum, ratio,
Jerry James <james@xemacs.org>
parents:
5736
diff
changeset
|
144 init_number_gmp (void) |
1983 | 145 { |
2367 | 146 mp_set_memory_functions ((void *(*) (size_t)) xmalloc, gmp_realloc, |
147 gmp_free); | |
1983 | 148 |
4612
313c2cc696b9
Fix the broken bigfloat-to-string conversion function.
Jerry James <james@xemacs.org>
parents:
2956
diff
changeset
|
149 /* Numbers with smaller exponents than this are printed in scientific |
313c2cc696b9
Fix the broken bigfloat-to-string conversion function.
Jerry James <james@xemacs.org>
parents:
2956
diff
changeset
|
150 notation. */ |
313c2cc696b9
Fix the broken bigfloat-to-string conversion function.
Jerry James <james@xemacs.org>
parents:
2956
diff
changeset
|
151 float_print_min = -4; |
1983 | 152 |
4612
313c2cc696b9
Fix the broken bigfloat-to-string conversion function.
Jerry James <james@xemacs.org>
parents:
2956
diff
changeset
|
153 /* Numbers with larger exponents than this are printed in scientific |
313c2cc696b9
Fix the broken bigfloat-to-string conversion function.
Jerry James <james@xemacs.org>
parents:
2956
diff
changeset
|
154 notation. */ |
313c2cc696b9
Fix the broken bigfloat-to-string conversion function.
Jerry James <james@xemacs.org>
parents:
2956
diff
changeset
|
155 float_print_max = 8; |
1983 | 156 |
157 /* Prepare the bignum/bigfloat random number generator */ | |
158 gmp_randinit_default (random_state); | |
159 gmp_randseed_ui (random_state, qxe_getpid () + time (NULL)); | |
160 } |