annotate libass/ass_strtod.c @ 30936:50b51e6987bd

Replace some "m" constraints by MANGLE to avoid issues with some compilers not being able to compile it and deduplicate the code at the same time.
author reimar
date Wed, 31 Mar 2010 17:00:33 +0000
parents 48d020c5ceca
children e64df5862cea
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
30200
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
1 /*
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
2 * Copyright (c) 1988-1993 The Regents of the University of California.
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
3 * Copyright (c) 1994 Sun Microsystems, Inc.
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
4 *
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
5 * Permission to use, copy, modify, and distribute this
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
6 * software and its documentation for any purpose and without
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
7 * fee is hereby granted, provided that the above copyright
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
8 * notice appear in all copies. The University of California
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
9 * makes no representations about the suitability of this
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
10 * software for any purpose. It is provided "as is" without
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
11 * express or implied warranty.
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
12 *
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
13 */
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
14
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
15 #include <stdlib.h>
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
16 #include <ctype.h>
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
17 #include <errno.h>
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
18
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
19 static int maxExponent = 511; /* Largest possible base 10 exponent. Any
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
20 * exponent larger than this will already
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
21 * produce underflow or overflow, so there's
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
22 * no need to worry about additional digits.
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
23 */
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
24
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
25 static double powersOf10[] = { /* Table giving binary powers of 10. Entry */
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
26 10., /* is 10^2^i. Used to convert decimal */
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
27 100., /* exponents into floating-point numbers. */
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
28 1.0e4,
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
29 1.0e8,
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
30 1.0e16,
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
31 1.0e32,
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
32 1.0e64,
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
33 1.0e128,
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
34 1.0e256
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
35 };
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
36
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
37 /*
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
38 *----------------------------------------------------------------------
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
39 *
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
40 * strtod --
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
41 *
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
42 * This procedure converts a floating-point number from an ASCII
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
43 * decimal representation to internal double-precision format.
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
44 *
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
45 * Results:
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
46 * The return value is the double-precision floating-point
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
47 * representation of the characters in string. If endPtr isn't
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
48 * NULL, then *endPtr is filled in with the address of the
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
49 * next character after the last one that was part of the
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
50 * floating-point number.
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
51 *
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
52 * Side effects:
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
53 * None.
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
54 *
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
55 *----------------------------------------------------------------------
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
56 */
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
57
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
58 double
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
59 ass_strtod(string, endPtr)
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
60 const char *string; /* A decimal ASCII floating-point number,
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
61 * optionally preceded by white space.
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
62 * Must have form "-I.FE-X", where I is the
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
63 * integer part of the mantissa, F is the
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
64 * fractional part of the mantissa, and X
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
65 * is the exponent. Either of the signs
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
66 * may be "+", "-", or omitted. Either I
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
67 * or F may be omitted, or both. The decimal
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
68 * point isn't necessary unless F is present.
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
69 * The "E" may actually be an "e". E and X
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
70 * may both be omitted (but not just one).
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
71 */
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
72 char **endPtr; /* If non-NULL, store terminating character's
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
73 * address here. */
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
74 {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
75 int sign, expSign = 0;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
76 double fraction, dblExp, *d;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
77 register const char *p;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
78 register int c;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
79 int exp = 0; /* Exponent read from "EX" field. */
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
80 int fracExp = 0; /* Exponent that derives from the fractional
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
81 * part. Under normal circumstatnces, it is
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
82 * the negative of the number of digits in F.
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
83 * However, if I is very long, the last digits
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
84 * of I get dropped (otherwise a long I with a
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
85 * large negative exponent could cause an
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
86 * unnecessary overflow on I alone). In this
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
87 * case, fracExp is incremented one for each
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
88 * dropped digit. */
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
89 int mantSize; /* Number of digits in mantissa. */
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
90 int decPt; /* Number of mantissa digits BEFORE decimal
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
91 * point. */
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
92 const char *pExp; /* Temporarily holds location of exponent
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
93 * in string. */
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
94
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
95 /*
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
96 * Strip off leading blanks and check for a sign.
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
97 */
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
98
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
99 p = string;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
100 while (isspace(*p)) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
101 p += 1;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
102 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
103 if (*p == '-') {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
104 sign = 1;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
105 p += 1;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
106 } else {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
107 if (*p == '+') {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
108 p += 1;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
109 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
110 sign = 0;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
111 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
112
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
113 /*
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
114 * Count the number of digits in the mantissa (including the decimal
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
115 * point), and also locate the decimal point.
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
116 */
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
117
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
118 decPt = -1;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
119 for (mantSize = 0; ; mantSize += 1)
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
120 {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
121 c = *p;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
122 if (!isdigit(c)) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
123 if ((c != '.') || (decPt >= 0)) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
124 break;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
125 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
126 decPt = mantSize;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
127 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
128 p += 1;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
129 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
130
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
131 /*
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
132 * Now suck up the digits in the mantissa. Use two integers to
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
133 * collect 9 digits each (this is faster than using floating-point).
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
134 * If the mantissa has more than 18 digits, ignore the extras, since
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
135 * they can't affect the value anyway.
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
136 */
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
137
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
138 pExp = p;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
139 p -= mantSize;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
140 if (decPt < 0) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
141 decPt = mantSize;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
142 } else {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
143 mantSize -= 1; /* One of the digits was the point. */
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
144 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
145 if (mantSize > 18) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
146 fracExp = decPt - 18;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
147 mantSize = 18;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
148 } else {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
149 fracExp = decPt - mantSize;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
150 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
151 if (mantSize == 0) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
152 fraction = 0.0;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
153 p = string;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
154 goto done;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
155 } else {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
156 int frac1, frac2;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
157 frac1 = 0;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
158 for ( ; mantSize > 9; mantSize -= 1)
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
159 {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
160 c = *p;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
161 p += 1;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
162 if (c == '.') {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
163 c = *p;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
164 p += 1;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
165 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
166 frac1 = 10*frac1 + (c - '0');
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
167 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
168 frac2 = 0;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
169 for (; mantSize > 0; mantSize -= 1)
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
170 {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
171 c = *p;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
172 p += 1;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
173 if (c == '.') {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
174 c = *p;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
175 p += 1;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
176 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
177 frac2 = 10*frac2 + (c - '0');
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
178 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
179 fraction = (1.0e9 * frac1) + frac2;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
180 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
181
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
182 /*
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
183 * Skim off the exponent.
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
184 */
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
185
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
186 p = pExp;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
187 if ((*p == 'E') || (*p == 'e')) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
188 p += 1;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
189 if (*p == '-') {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
190 expSign = 1;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
191 p += 1;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
192 } else {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
193 if (*p == '+') {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
194 p += 1;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
195 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
196 expSign = 0;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
197 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
198 while (isdigit(*p)) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
199 exp = exp * 10 + (*p - '0');
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
200 p += 1;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
201 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
202 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
203 if (expSign) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
204 exp = fracExp - exp;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
205 } else {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
206 exp = fracExp + exp;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
207 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
208
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
209 /*
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
210 * Generate a floating-point number that represents the exponent.
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
211 * Do this by processing the exponent one bit at a time to combine
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
212 * many powers of 2 of 10. Then combine the exponent with the
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
213 * fraction.
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
214 */
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
215
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
216 if (exp < 0) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
217 expSign = 1;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
218 exp = -exp;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
219 } else {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
220 expSign = 0;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
221 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
222 if (exp > maxExponent) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
223 exp = maxExponent;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
224 errno = ERANGE;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
225 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
226 dblExp = 1.0;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
227 for (d = powersOf10; exp != 0; exp >>= 1, d += 1) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
228 if (exp & 01) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
229 dblExp *= *d;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
230 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
231 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
232 if (expSign) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
233 fraction /= dblExp;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
234 } else {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
235 fraction *= dblExp;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
236 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
237
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
238 done:
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
239 if (endPtr != NULL) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
240 *endPtr = (char *) p;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
241 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
242
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
243 if (sign) {
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
244 return -fraction;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
245 }
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
246 return fraction;
48d020c5ceca Update internal libass copy to commit 8db4a5
greg
parents:
diff changeset
247 }