Mercurial > hg > octave-kai > gnulib-hg
annotate lib/printf-frexp.c @ 9309:bbbbbf4cd1c5
Change copyright notice from GPLv2+ to GPLv3+.
author | Bruno Haible <bruno@clisp.org> |
---|---|
date | Sun, 07 Oct 2007 19:14:58 +0200 |
parents | 359d135f748c |
children | bec01fc15c2f |
rev | line source |
---|---|
8240 | 1 /* Split a double into fraction and mantissa, for hexadecimal printf. |
2 Copyright (C) 2007 Free Software Foundation, Inc. | |
3 | |
9309
bbbbbf4cd1c5
Change copyright notice from GPLv2+ to GPLv3+.
Bruno Haible <bruno@clisp.org>
parents:
8648
diff
changeset
|
4 This program is free software: you can redistribute it and/or modify |
8240 | 5 it under the terms of the GNU General Public License as published by |
9309
bbbbbf4cd1c5
Change copyright notice from GPLv2+ to GPLv3+.
Bruno Haible <bruno@clisp.org>
parents:
8648
diff
changeset
|
6 the Free Software Foundation; either version 3 of the License, or |
bbbbbf4cd1c5
Change copyright notice from GPLv2+ to GPLv3+.
Bruno Haible <bruno@clisp.org>
parents:
8648
diff
changeset
|
7 (at your option) any later version. |
8240 | 8 |
9 This program is distributed in the hope that it will be useful, | |
10 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 GNU General Public License for more details. | |
13 | |
9309
bbbbbf4cd1c5
Change copyright notice from GPLv2+ to GPLv3+.
Bruno Haible <bruno@clisp.org>
parents:
8648
diff
changeset
|
14 You should have received a copy of the GNU General Public License |
bbbbbf4cd1c5
Change copyright notice from GPLv2+ to GPLv3+.
Bruno Haible <bruno@clisp.org>
parents:
8648
diff
changeset
|
15 along with this program. If not, see <http://www.gnu.org/licenses/>. */ |
8240 | 16 |
17 #include <config.h> | |
18 | |
8648
359d135f748c
Assume 'long double' exists.
Bruno Haible <bruno@clisp.org>
parents:
8535
diff
changeset
|
19 /* Specification. */ |
359d135f748c
Assume 'long double' exists.
Bruno Haible <bruno@clisp.org>
parents:
8535
diff
changeset
|
20 #ifdef USE_LONG_DOUBLE |
359d135f748c
Assume 'long double' exists.
Bruno Haible <bruno@clisp.org>
parents:
8535
diff
changeset
|
21 # include "printf-frexpl.h" |
359d135f748c
Assume 'long double' exists.
Bruno Haible <bruno@clisp.org>
parents:
8535
diff
changeset
|
22 #else |
359d135f748c
Assume 'long double' exists.
Bruno Haible <bruno@clisp.org>
parents:
8535
diff
changeset
|
23 # include "printf-frexp.h" |
359d135f748c
Assume 'long double' exists.
Bruno Haible <bruno@clisp.org>
parents:
8535
diff
changeset
|
24 #endif |
8240 | 25 |
8648
359d135f748c
Assume 'long double' exists.
Bruno Haible <bruno@clisp.org>
parents:
8535
diff
changeset
|
26 #include <float.h> |
359d135f748c
Assume 'long double' exists.
Bruno Haible <bruno@clisp.org>
parents:
8535
diff
changeset
|
27 #include <math.h> |
359d135f748c
Assume 'long double' exists.
Bruno Haible <bruno@clisp.org>
parents:
8535
diff
changeset
|
28 #ifdef USE_LONG_DOUBLE |
359d135f748c
Assume 'long double' exists.
Bruno Haible <bruno@clisp.org>
parents:
8535
diff
changeset
|
29 # include "fpucw.h" |
359d135f748c
Assume 'long double' exists.
Bruno Haible <bruno@clisp.org>
parents:
8535
diff
changeset
|
30 #endif |
8240 | 31 |
8253
c59696ff6dbc
Add comment about FLT_RADIX.
Bruno Haible <bruno@clisp.org>
parents:
8252
diff
changeset
|
32 /* This file assumes FLT_RADIX = 2. If FLT_RADIX is a power of 2 greater |
c59696ff6dbc
Add comment about FLT_RADIX.
Bruno Haible <bruno@clisp.org>
parents:
8252
diff
changeset
|
33 than 2, or not even a power of 2, some rounding errors can occur, so that |
c59696ff6dbc
Add comment about FLT_RADIX.
Bruno Haible <bruno@clisp.org>
parents:
8252
diff
changeset
|
34 then the returned mantissa is only guaranteed to be <= 2.0, not < 2.0. */ |
c59696ff6dbc
Add comment about FLT_RADIX.
Bruno Haible <bruno@clisp.org>
parents:
8252
diff
changeset
|
35 |
8648
359d135f748c
Assume 'long double' exists.
Bruno Haible <bruno@clisp.org>
parents:
8535
diff
changeset
|
36 #ifdef USE_LONG_DOUBLE |
359d135f748c
Assume 'long double' exists.
Bruno Haible <bruno@clisp.org>
parents:
8535
diff
changeset
|
37 # define FUNC printf_frexpl |
359d135f748c
Assume 'long double' exists.
Bruno Haible <bruno@clisp.org>
parents:
8535
diff
changeset
|
38 # define DOUBLE long double |
359d135f748c
Assume 'long double' exists.
Bruno Haible <bruno@clisp.org>
parents:
8535
diff
changeset
|
39 # define MIN_EXP LDBL_MIN_EXP |
359d135f748c
Assume 'long double' exists.
Bruno Haible <bruno@clisp.org>
parents:
8535
diff
changeset
|
40 # if HAVE_FREXPL_IN_LIBC && HAVE_LDEXPL_IN_LIBC |
359d135f748c
Assume 'long double' exists.
Bruno Haible <bruno@clisp.org>
parents:
8535
diff
changeset
|
41 # define USE_FREXP_LDEXP |
359d135f748c
Assume 'long double' exists.
Bruno Haible <bruno@clisp.org>
parents:
8535
diff
changeset
|
42 # define FREXP frexpl |
359d135f748c
Assume 'long double' exists.
Bruno Haible <bruno@clisp.org>
parents:
8535
diff
changeset
|
43 # define LDEXP ldexpl |
8240 | 44 # endif |
8648
359d135f748c
Assume 'long double' exists.
Bruno Haible <bruno@clisp.org>
parents:
8535
diff
changeset
|
45 # define DECL_ROUNDING DECL_LONG_DOUBLE_ROUNDING |
359d135f748c
Assume 'long double' exists.
Bruno Haible <bruno@clisp.org>
parents:
8535
diff
changeset
|
46 # define BEGIN_ROUNDING() BEGIN_LONG_DOUBLE_ROUNDING () |
359d135f748c
Assume 'long double' exists.
Bruno Haible <bruno@clisp.org>
parents:
8535
diff
changeset
|
47 # define END_ROUNDING() END_LONG_DOUBLE_ROUNDING () |
359d135f748c
Assume 'long double' exists.
Bruno Haible <bruno@clisp.org>
parents:
8535
diff
changeset
|
48 # define L_(literal) literal##L |
359d135f748c
Assume 'long double' exists.
Bruno Haible <bruno@clisp.org>
parents:
8535
diff
changeset
|
49 #else |
359d135f748c
Assume 'long double' exists.
Bruno Haible <bruno@clisp.org>
parents:
8535
diff
changeset
|
50 # define FUNC printf_frexp |
359d135f748c
Assume 'long double' exists.
Bruno Haible <bruno@clisp.org>
parents:
8535
diff
changeset
|
51 # define DOUBLE double |
359d135f748c
Assume 'long double' exists.
Bruno Haible <bruno@clisp.org>
parents:
8535
diff
changeset
|
52 # define MIN_EXP DBL_MIN_EXP |
359d135f748c
Assume 'long double' exists.
Bruno Haible <bruno@clisp.org>
parents:
8535
diff
changeset
|
53 # if HAVE_FREXP_IN_LIBC && HAVE_LDEXP_IN_LIBC |
359d135f748c
Assume 'long double' exists.
Bruno Haible <bruno@clisp.org>
parents:
8535
diff
changeset
|
54 # define USE_FREXP_LDEXP |
359d135f748c
Assume 'long double' exists.
Bruno Haible <bruno@clisp.org>
parents:
8535
diff
changeset
|
55 # define FREXP frexp |
359d135f748c
Assume 'long double' exists.
Bruno Haible <bruno@clisp.org>
parents:
8535
diff
changeset
|
56 # define LDEXP ldexp |
359d135f748c
Assume 'long double' exists.
Bruno Haible <bruno@clisp.org>
parents:
8535
diff
changeset
|
57 # endif |
359d135f748c
Assume 'long double' exists.
Bruno Haible <bruno@clisp.org>
parents:
8535
diff
changeset
|
58 # define DECL_ROUNDING |
359d135f748c
Assume 'long double' exists.
Bruno Haible <bruno@clisp.org>
parents:
8535
diff
changeset
|
59 # define BEGIN_ROUNDING() |
359d135f748c
Assume 'long double' exists.
Bruno Haible <bruno@clisp.org>
parents:
8535
diff
changeset
|
60 # define END_ROUNDING() |
359d135f748c
Assume 'long double' exists.
Bruno Haible <bruno@clisp.org>
parents:
8535
diff
changeset
|
61 # define L_(literal) literal |
359d135f748c
Assume 'long double' exists.
Bruno Haible <bruno@clisp.org>
parents:
8535
diff
changeset
|
62 #endif |
8240 | 63 |
64 DOUBLE | |
65 FUNC (DOUBLE x, int *exp) | |
66 { | |
67 int exponent; | |
8531 | 68 DECL_ROUNDING |
69 | |
70 BEGIN_ROUNDING (); | |
8240 | 71 |
8648
359d135f748c
Assume 'long double' exists.
Bruno Haible <bruno@clisp.org>
parents:
8535
diff
changeset
|
72 #ifdef USE_FREXP_LDEXP |
8240 | 73 /* frexp and ldexp are usually faster than the loop below. */ |
74 x = FREXP (x, &exponent); | |
75 | |
76 x = x + x; | |
77 exponent -= 1; | |
78 | |
79 if (exponent < MIN_EXP - 1) | |
80 { | |
81 x = LDEXP (x, exponent - (MIN_EXP - 1)); | |
82 exponent = MIN_EXP - 1; | |
83 } | |
8648
359d135f748c
Assume 'long double' exists.
Bruno Haible <bruno@clisp.org>
parents:
8535
diff
changeset
|
84 #else |
8535
530583a3b054
Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents:
8531
diff
changeset
|
85 { |
530583a3b054
Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents:
8531
diff
changeset
|
86 /* Since the exponent is an 'int', it fits in 64 bits. Therefore the |
530583a3b054
Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents:
8531
diff
changeset
|
87 loops are executed no more than 64 times. */ |
530583a3b054
Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents:
8531
diff
changeset
|
88 DOUBLE pow2[64]; /* pow2[i] = 2^2^i */ |
530583a3b054
Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents:
8531
diff
changeset
|
89 DOUBLE powh[64]; /* powh[i] = 2^-2^i */ |
530583a3b054
Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents:
8531
diff
changeset
|
90 int i; |
530583a3b054
Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents:
8531
diff
changeset
|
91 |
530583a3b054
Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents:
8531
diff
changeset
|
92 exponent = 0; |
530583a3b054
Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents:
8531
diff
changeset
|
93 if (x >= L_(1.0)) |
530583a3b054
Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents:
8531
diff
changeset
|
94 { |
530583a3b054
Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents:
8531
diff
changeset
|
95 /* A nonnegative exponent. */ |
530583a3b054
Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents:
8531
diff
changeset
|
96 { |
530583a3b054
Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents:
8531
diff
changeset
|
97 DOUBLE pow2_i; /* = pow2[i] */ |
530583a3b054
Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents:
8531
diff
changeset
|
98 DOUBLE powh_i; /* = powh[i] */ |
8240 | 99 |
8535
530583a3b054
Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents:
8531
diff
changeset
|
100 /* Invariants: pow2_i = 2^2^i, powh_i = 2^-2^i, |
530583a3b054
Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents:
8531
diff
changeset
|
101 x * 2^exponent = argument, x >= 1.0. */ |
530583a3b054
Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents:
8531
diff
changeset
|
102 for (i = 0, pow2_i = L_(2.0), powh_i = L_(0.5); |
530583a3b054
Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents:
8531
diff
changeset
|
103 ; |
530583a3b054
Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents:
8531
diff
changeset
|
104 i++, pow2_i = pow2_i * pow2_i, powh_i = powh_i * powh_i) |
530583a3b054
Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents:
8531
diff
changeset
|
105 { |
530583a3b054
Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents:
8531
diff
changeset
|
106 if (x >= pow2_i) |
530583a3b054
Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents:
8531
diff
changeset
|
107 { |
530583a3b054
Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents:
8531
diff
changeset
|
108 exponent += (1 << i); |
530583a3b054
Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents:
8531
diff
changeset
|
109 x *= powh_i; |
530583a3b054
Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents:
8531
diff
changeset
|
110 } |
530583a3b054
Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents:
8531
diff
changeset
|
111 else |
530583a3b054
Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents:
8531
diff
changeset
|
112 break; |
530583a3b054
Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents:
8531
diff
changeset
|
113 |
530583a3b054
Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents:
8531
diff
changeset
|
114 pow2[i] = pow2_i; |
530583a3b054
Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents:
8531
diff
changeset
|
115 powh[i] = powh_i; |
530583a3b054
Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents:
8531
diff
changeset
|
116 } |
530583a3b054
Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents:
8531
diff
changeset
|
117 } |
530583a3b054
Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents:
8531
diff
changeset
|
118 /* Here 1.0 <= x < 2^2^i. */ |
530583a3b054
Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents:
8531
diff
changeset
|
119 } |
530583a3b054
Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents:
8531
diff
changeset
|
120 else |
8240 | 121 { |
8535
530583a3b054
Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents:
8531
diff
changeset
|
122 /* A negative exponent. */ |
530583a3b054
Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents:
8531
diff
changeset
|
123 { |
530583a3b054
Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents:
8531
diff
changeset
|
124 DOUBLE pow2_i; /* = pow2[i] */ |
530583a3b054
Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents:
8531
diff
changeset
|
125 DOUBLE powh_i; /* = powh[i] */ |
8240 | 126 |
8535
530583a3b054
Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents:
8531
diff
changeset
|
127 /* Invariants: pow2_i = 2^2^i, powh_i = 2^-2^i, |
530583a3b054
Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents:
8531
diff
changeset
|
128 x * 2^exponent = argument, x < 1.0, exponent >= MIN_EXP - 1. */ |
530583a3b054
Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents:
8531
diff
changeset
|
129 for (i = 0, pow2_i = L_(2.0), powh_i = L_(0.5); |
530583a3b054
Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents:
8531
diff
changeset
|
130 ; |
530583a3b054
Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents:
8531
diff
changeset
|
131 i++, pow2_i = pow2_i * pow2_i, powh_i = powh_i * powh_i) |
530583a3b054
Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents:
8531
diff
changeset
|
132 { |
530583a3b054
Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents:
8531
diff
changeset
|
133 if (exponent - (1 << i) < MIN_EXP - 1) |
530583a3b054
Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents:
8531
diff
changeset
|
134 break; |
530583a3b054
Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents:
8531
diff
changeset
|
135 |
530583a3b054
Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents:
8531
diff
changeset
|
136 exponent -= (1 << i); |
530583a3b054
Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents:
8531
diff
changeset
|
137 x *= pow2_i; |
530583a3b054
Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents:
8531
diff
changeset
|
138 if (x >= L_(1.0)) |
530583a3b054
Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents:
8531
diff
changeset
|
139 break; |
530583a3b054
Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents:
8531
diff
changeset
|
140 |
530583a3b054
Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents:
8531
diff
changeset
|
141 pow2[i] = pow2_i; |
530583a3b054
Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents:
8531
diff
changeset
|
142 powh[i] = powh_i; |
530583a3b054
Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents:
8531
diff
changeset
|
143 } |
530583a3b054
Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents:
8531
diff
changeset
|
144 } |
530583a3b054
Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents:
8531
diff
changeset
|
145 /* Here either x < 1.0 and exponent - 2^i < MIN_EXP - 1 <= exponent, |
530583a3b054
Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents:
8531
diff
changeset
|
146 or 1.0 <= x < 2^2^i and exponent >= MIN_EXP - 1. */ |
530583a3b054
Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents:
8531
diff
changeset
|
147 |
530583a3b054
Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents:
8531
diff
changeset
|
148 if (x < L_(1.0)) |
530583a3b054
Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents:
8531
diff
changeset
|
149 /* Invariants: x * 2^exponent = argument, x < 1.0 and |
530583a3b054
Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents:
8531
diff
changeset
|
150 exponent - 2^i < MIN_EXP - 1 <= exponent. */ |
530583a3b054
Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents:
8531
diff
changeset
|
151 while (i > 0) |
530583a3b054
Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents:
8531
diff
changeset
|
152 { |
530583a3b054
Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents:
8531
diff
changeset
|
153 i--; |
530583a3b054
Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents:
8531
diff
changeset
|
154 if (exponent - (1 << i) >= MIN_EXP - 1) |
530583a3b054
Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents:
8531
diff
changeset
|
155 { |
530583a3b054
Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents:
8531
diff
changeset
|
156 exponent -= (1 << i); |
530583a3b054
Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents:
8531
diff
changeset
|
157 x *= pow2[i]; |
530583a3b054
Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents:
8531
diff
changeset
|
158 if (x >= L_(1.0)) |
530583a3b054
Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents:
8531
diff
changeset
|
159 break; |
530583a3b054
Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents:
8531
diff
changeset
|
160 } |
530583a3b054
Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents:
8531
diff
changeset
|
161 } |
530583a3b054
Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents:
8531
diff
changeset
|
162 |
530583a3b054
Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents:
8531
diff
changeset
|
163 /* Here either x < 1.0 and exponent = MIN_EXP - 1, |
530583a3b054
Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents:
8531
diff
changeset
|
164 or 1.0 <= x < 2^2^i and exponent >= MIN_EXP - 1. */ |
530583a3b054
Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents:
8531
diff
changeset
|
165 } |
530583a3b054
Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents:
8531
diff
changeset
|
166 |
530583a3b054
Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents:
8531
diff
changeset
|
167 /* Invariants: x * 2^exponent = argument, and |
530583a3b054
Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents:
8531
diff
changeset
|
168 either x < 1.0 and exponent = MIN_EXP - 1, |
530583a3b054
Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents:
8531
diff
changeset
|
169 or 1.0 <= x < 2^2^i and exponent >= MIN_EXP - 1. */ |
530583a3b054
Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents:
8531
diff
changeset
|
170 while (i > 0) |
530583a3b054
Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents:
8531
diff
changeset
|
171 { |
530583a3b054
Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents:
8531
diff
changeset
|
172 i--; |
530583a3b054
Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents:
8531
diff
changeset
|
173 if (x >= pow2[i]) |
8240 | 174 { |
8535
530583a3b054
Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents:
8531
diff
changeset
|
175 exponent += (1 << i); |
530583a3b054
Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents:
8531
diff
changeset
|
176 x *= powh[i]; |
8240 | 177 } |
178 } | |
8535
530583a3b054
Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents:
8531
diff
changeset
|
179 /* Here either x < 1.0 and exponent = MIN_EXP - 1, |
530583a3b054
Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents:
8531
diff
changeset
|
180 or 1.0 <= x < 2.0 and exponent >= MIN_EXP - 1. */ |
530583a3b054
Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents:
8531
diff
changeset
|
181 } |
8648
359d135f748c
Assume 'long double' exists.
Bruno Haible <bruno@clisp.org>
parents:
8535
diff
changeset
|
182 #endif |
8240 | 183 |
8531 | 184 END_ROUNDING (); |
185 | |
8240 | 186 *exp = exponent; |
187 return x; | |
188 } |