Mercurial > hg > xemacs-beta
view src/number-gmp.c @ 5724:ede80ef92a74
Make soft links in src for module source files, if built in to the executable.
This ensures that those files are built with the same compiler flags as all
other source files.
See these xemacs-beta messages:
<CAHCOHQn+q=Xuwq+y68dvqi7afAP9f-TdB7=8YiZ8VYO816sjHg@mail.gmail.com>
<f5by5ejqiyk.fsf@calexico.inf.ed.ac.uk>
author | Jerry James <james@xemacs.org> |
---|---|
date | Sat, 02 Mar 2013 14:32:37 -0700 |
parents | 2aa9cd456ae7 |
children | 3192994c49ca |
line wrap: on
line source
/* Numeric types for XEmacs using the GNU MP library. Copyright (C) 2004 Jerry James. This file is part of XEmacs. XEmacs is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. XEmacs is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with XEmacs. If not, see <http://www.gnu.org/licenses/>. */ /* Synched up with: Not in FSF. */ #include <config.h> #include <limits.h> #include <math.h> #include "lisp.h" #include "sysproc.h" /* For qxe_getpid */ static mp_exp_t float_print_min, float_print_max; gmp_randstate_t random_state; CIbyte * bigfloat_to_string(mpf_t f, int base) { mp_exp_t expt; CIbyte *str = mpf_get_str (NULL, &expt, base, 0, f); const int sign = mpf_sgn (f); const int neg = (sign < 0) ? 1 : 0; int len = strlen (str) + 1; /* Count the null terminator */ if (sign == 0) { XREALLOC_ARRAY (str, CIbyte, 4); strncpy (str, "0.0", 4); } else if (float_print_min <= expt && expt <= float_print_max) { if (expt < 0) { /* We need room for a radix point and leading zeroes */ const int space = -expt + 2; XREALLOC_ARRAY (str, CIbyte, len + space); memmove (&str[space + neg], &str[neg], len - neg); memset (&str[neg], '0', space); str[neg + 1] = '.'; } else if (len <= expt + neg + 1) { /* We need room for a radix point and trailing zeroes */ XREALLOC_ARRAY (str, CIbyte, expt + neg + 3); memset (&str[len - 1], '0', expt + neg + 3 - len); str[expt + neg] = '.'; str[expt + neg + 2] = '\0'; } else { /* We just need room for a radix point */ XREALLOC_ARRAY (str, CIbyte, len + 1); memmove (&str[expt + neg + 1], &str[expt + neg], len - (expt + neg)); str[expt + neg] = '.'; } } else { /* Computerized scientific notation: We need room for a possible radix point, format identifier, and exponent */ /* GMP's idea of the exponent is 1 greater than scientific notation's */ expt--; { const int point = (len == neg + 2) ? 0 : 1; const int exponent = (expt < 0) ? (int)(log ((double) (-expt)) / log ((double) base)) + 3 : (int)(log ((double) expt) / log ((double) base)) + 2; const int space = point + exponent; XREALLOC_ARRAY (str, CIbyte, len + space); if (point > 0) { memmove (&str[neg + 2], &str[neg + 1], len - neg); str[neg + 1] = '.'; } sprintf (&str[len + point - 1], "E%ld", expt); } } return str; } /* We need the next two functions since GNU MP insists on giving us an extra parameter. */ static void *gmp_realloc (void *ptr, size_t UNUSED (old_size), size_t new_size) { return xrealloc (ptr, new_size); } static void gmp_free (void *ptr, size_t UNUSED (size)) { xfree (ptr); } void init_number_gmp () { mp_set_memory_functions ((void *(*) (size_t)) xmalloc, gmp_realloc, gmp_free); /* Numbers with smaller exponents than this are printed in scientific notation. */ float_print_min = -4; /* Numbers with larger exponents than this are printed in scientific notation. */ float_print_max = 8; /* Prepare the bignum/bigfloat random number generator */ gmp_randinit_default (random_state); gmp_randseed_ui (random_state, qxe_getpid () + time (NULL)); }