1 /* The authors of this software are Rob Pike and Ken Thompson.
2 * Copyright (c) 2002 by Lucent Technologies.
3 * Permission to use, copy, modify, and distribute this software for any
4 * purpose without fee is hereby granted, provided that this entire notice
5 * is included in all copies of any software which is or includes a copy
6 * or modification of this software and in all copies of the supporting
7 * documentation for such software.
8 * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
9 * WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY
10 * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
11 * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
14 #include "mupdf/fitz.h"
24 #define INFINITY (DBL_MAX+DBL_MAX)
27 #define NAN (INFINITY-INFINITY)
32 typedef unsigned long ulong;
38 * first few powers of 10
40 static float pows10[] =
42 1e0f, 1e1f, 1e2f, 1e3f, 1e4f, 1e5f, 1e6f, 1e7f, 1e8f, 1e9f,
43 1e10f, 1e11f, 1e12f, 1e13f, 1e14f, 1e15f, 1e16f, 1e17f, 1e18f, 1e19f,
44 1e20f, 1e21f, 1e22f, 1e23f, 1e24f, 1e25f, 1e26f, 1e27f, 1e28f, 1e29f,
45 1e30f, 1e31f, 1e32f, 1e33f, 1e34f, 1e35f, 1e36f, 1e37f, 1e38f
47 #define npows10 ((int)(sizeof(pows10)/sizeof(pows10[0])))
48 #define pow10(x) fmtpow10(x)
65 d = pows10[npows10-1];
72 d *= pows10[npows10 - 1];
81 * add 1 to the decimal integer string a of length n.
82 * if 99999 overflows into 10000, return 1 to tell caller
83 * to move the virtual decimal point.
91 if(n < 0 || n > NSIGNIF)
93 for(b = a+n-1; b >= a; b--) {
102 * need to overflow adding digit.
103 * shift number down and insert 1 at beginning.
104 * decimal is known to be 0s or we wouldn't
105 * have gotten this far. (e.g., 99999+1 => 00000)
112 * subtract 1 from the decimal integer string a.
113 * if 10000 underflows into 09999, make it 99999
114 * and return 1 to tell caller to move the virtual
115 * decimal point. this way, xsub1 is inverse of xadd1.
118 xsub1(char *a, int n)
123 if(n < 0 || n > NSIGNIF)
125 for(b = a+n-1; b >= a; b--) {
128 if(c == '0' && b == a) {
130 * just zeroed the top digit; shift everyone up.
131 * decimal is known to be 9s or we wouldn't
132 * have gotten this far. (e.g., 10000-1 => 09999)
143 * can't get here. the number a is always normalized
144 * so that it has a nonzero first digit.
150 * format exponent like sprintf(p, "e%+d", e)
153 fmtexp(char *p, int e)
166 se[i++] = e % 10 + '0';
177 * compute decimal integer m, exp such that:
179 * m is as short as possible with losing exactness
180 * assumes special cases (NaN, +Inf, -Inf) have been handled.
183 fz_ftoa(float f, char *s, int *exp, int *neg, int *ns)
185 int c, d, e2, e, ee, i, ndigit, oerrno;
186 char tmp[NSIGNIF+10];
189 oerrno = errno; /* in case strtod smashes errno */
192 * make f non-negative.
201 * must handle zero specially.
212 * find g,e such that f = g*10^e.
213 * guess 10-exponent using 2-exponent, then fine tune.
216 e = (int)(e2 * .301029995664f);
228 * convert NSIGNIF digits as a first approximation.
230 for(i=0; i<NSIGNIF; i++) {
238 * adjust e because s is 314159... not 3.14159...
241 fmtexp(s+NSIGNIF, e);
244 * adjust conversion until strtod(s) == f exactly.
246 for(i=0; i<10; i++) {
247 g = fz_strtod(s, NULL);
249 if(xadd1(s, NSIGNIF)) {
252 fmtexp(s+NSIGNIF, e);
257 if(xsub1(s, NSIGNIF)) {
260 fmtexp(s+NSIGNIF, e);
268 * play with the decimal to try to simplify.
272 * bump last few digits up to 9 if we can
274 for(i=NSIGNIF-1; i>=NSIGNIF-3; i--) {
278 g = fz_strtod(s, NULL);
287 * add 1 in hopes of turning 9s to 0s
289 if(s[NSIGNIF-1] == '9') {
292 if(xadd1(tmp, NSIGNIF)) {
294 fmtexp(tmp+NSIGNIF, ee);
296 g = fz_strtod(tmp, NULL);
304 * bump last few digits down to 0 as we can.
306 for(i=NSIGNIF-1; i>=NSIGNIF-3; i--) {
310 g = fz_strtod(s, NULL);
319 * remove trailing zeros.
322 while(ndigit > 1 && s[ndigit-1] == '0'){