annotate lib/printf-frexp.c @ 17464:290d581e2e24

autoupdate
author Karl Berry <karl@freefriends.org>
date Sat, 10 Aug 2013 07:10:55 -0700
parents e542fd46ad6f
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
8240
536315dcb204 New module 'printf-frexp'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1 /* Split a double into fraction and mantissa, for hexadecimal printf.
17249
e542fd46ad6f maint: update all copyright year number ranges
Eric Blake <eblake@redhat.com>
parents: 16201
diff changeset
2 Copyright (C) 2007, 2009-2013 Free Software Foundation, Inc.
8240
536315dcb204 New module 'printf-frexp'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
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
536315dcb204 New module 'printf-frexp'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
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
536315dcb204 New module 'printf-frexp'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
8
536315dcb204 New module 'printf-frexp'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
9 This program is distributed in the hope that it will be useful,
536315dcb204 New module 'printf-frexp'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
536315dcb204 New module 'printf-frexp'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
536315dcb204 New module 'printf-frexp'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
12 GNU General Public License for more details.
536315dcb204 New module 'printf-frexp'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
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
536315dcb204 New module 'printf-frexp'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
16
15933
6860d9f2e394 printf-frexpl: Simplify for platforms where 'long double' == 'double'.
Bruno Haible <bruno@clisp.org>
parents: 14079
diff changeset
17 #if ! defined USE_LONG_DOUBLE
6860d9f2e394 printf-frexpl: Simplify for platforms where 'long double' == 'double'.
Bruno Haible <bruno@clisp.org>
parents: 14079
diff changeset
18 # include <config.h>
6860d9f2e394 printf-frexpl: Simplify for platforms where 'long double' == 'double'.
Bruno Haible <bruno@clisp.org>
parents: 14079
diff changeset
19 #endif
8240
536315dcb204 New module 'printf-frexp'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
20
8648
359d135f748c Assume 'long double' exists.
Bruno Haible <bruno@clisp.org>
parents: 8535
diff changeset
21 /* Specification. */
359d135f748c Assume 'long double' exists.
Bruno Haible <bruno@clisp.org>
parents: 8535
diff changeset
22 #ifdef USE_LONG_DOUBLE
359d135f748c Assume 'long double' exists.
Bruno Haible <bruno@clisp.org>
parents: 8535
diff changeset
23 # include "printf-frexpl.h"
359d135f748c Assume 'long double' exists.
Bruno Haible <bruno@clisp.org>
parents: 8535
diff changeset
24 #else
359d135f748c Assume 'long double' exists.
Bruno Haible <bruno@clisp.org>
parents: 8535
diff changeset
25 # include "printf-frexp.h"
359d135f748c Assume 'long double' exists.
Bruno Haible <bruno@clisp.org>
parents: 8535
diff changeset
26 #endif
8240
536315dcb204 New module 'printf-frexp'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
27
8648
359d135f748c Assume 'long double' exists.
Bruno Haible <bruno@clisp.org>
parents: 8535
diff changeset
28 #include <float.h>
359d135f748c Assume 'long double' exists.
Bruno Haible <bruno@clisp.org>
parents: 8535
diff changeset
29 #include <math.h>
359d135f748c Assume 'long double' exists.
Bruno Haible <bruno@clisp.org>
parents: 8535
diff changeset
30 #ifdef USE_LONG_DOUBLE
359d135f748c Assume 'long double' exists.
Bruno Haible <bruno@clisp.org>
parents: 8535
diff changeset
31 # include "fpucw.h"
359d135f748c Assume 'long double' exists.
Bruno Haible <bruno@clisp.org>
parents: 8535
diff changeset
32 #endif
8240
536315dcb204 New module 'printf-frexp'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
33
8253
c59696ff6dbc Add comment about FLT_RADIX.
Bruno Haible <bruno@clisp.org>
parents: 8252
diff changeset
34 /* 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
35 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
36 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
37
8648
359d135f748c Assume 'long double' exists.
Bruno Haible <bruno@clisp.org>
parents: 8535
diff changeset
38 #ifdef USE_LONG_DOUBLE
359d135f748c Assume 'long double' exists.
Bruno Haible <bruno@clisp.org>
parents: 8535
diff changeset
39 # define FUNC printf_frexpl
359d135f748c Assume 'long double' exists.
Bruno Haible <bruno@clisp.org>
parents: 8535
diff changeset
40 # define DOUBLE long double
359d135f748c Assume 'long double' exists.
Bruno Haible <bruno@clisp.org>
parents: 8535
diff changeset
41 # define MIN_EXP LDBL_MIN_EXP
359d135f748c Assume 'long double' exists.
Bruno Haible <bruno@clisp.org>
parents: 8535
diff changeset
42 # if HAVE_FREXPL_IN_LIBC && HAVE_LDEXPL_IN_LIBC
359d135f748c Assume 'long double' exists.
Bruno Haible <bruno@clisp.org>
parents: 8535
diff changeset
43 # define USE_FREXP_LDEXP
359d135f748c Assume 'long double' exists.
Bruno Haible <bruno@clisp.org>
parents: 8535
diff changeset
44 # define FREXP frexpl
359d135f748c Assume 'long double' exists.
Bruno Haible <bruno@clisp.org>
parents: 8535
diff changeset
45 # define LDEXP ldexpl
8240
536315dcb204 New module 'printf-frexp'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
46 # endif
8648
359d135f748c Assume 'long double' exists.
Bruno Haible <bruno@clisp.org>
parents: 8535
diff changeset
47 # define DECL_ROUNDING DECL_LONG_DOUBLE_ROUNDING
359d135f748c Assume 'long double' exists.
Bruno Haible <bruno@clisp.org>
parents: 8535
diff changeset
48 # define BEGIN_ROUNDING() BEGIN_LONG_DOUBLE_ROUNDING ()
359d135f748c Assume 'long double' exists.
Bruno Haible <bruno@clisp.org>
parents: 8535
diff changeset
49 # define END_ROUNDING() END_LONG_DOUBLE_ROUNDING ()
359d135f748c Assume 'long double' exists.
Bruno Haible <bruno@clisp.org>
parents: 8535
diff changeset
50 # define L_(literal) literal##L
359d135f748c Assume 'long double' exists.
Bruno Haible <bruno@clisp.org>
parents: 8535
diff changeset
51 #else
359d135f748c Assume 'long double' exists.
Bruno Haible <bruno@clisp.org>
parents: 8535
diff changeset
52 # define FUNC printf_frexp
359d135f748c Assume 'long double' exists.
Bruno Haible <bruno@clisp.org>
parents: 8535
diff changeset
53 # define DOUBLE double
359d135f748c Assume 'long double' exists.
Bruno Haible <bruno@clisp.org>
parents: 8535
diff changeset
54 # define MIN_EXP DBL_MIN_EXP
359d135f748c Assume 'long double' exists.
Bruno Haible <bruno@clisp.org>
parents: 8535
diff changeset
55 # if HAVE_FREXP_IN_LIBC && HAVE_LDEXP_IN_LIBC
359d135f748c Assume 'long double' exists.
Bruno Haible <bruno@clisp.org>
parents: 8535
diff changeset
56 # define USE_FREXP_LDEXP
359d135f748c Assume 'long double' exists.
Bruno Haible <bruno@clisp.org>
parents: 8535
diff changeset
57 # define FREXP frexp
359d135f748c Assume 'long double' exists.
Bruno Haible <bruno@clisp.org>
parents: 8535
diff changeset
58 # define LDEXP ldexp
359d135f748c Assume 'long double' exists.
Bruno Haible <bruno@clisp.org>
parents: 8535
diff changeset
59 # endif
359d135f748c Assume 'long double' exists.
Bruno Haible <bruno@clisp.org>
parents: 8535
diff changeset
60 # define DECL_ROUNDING
359d135f748c Assume 'long double' exists.
Bruno Haible <bruno@clisp.org>
parents: 8535
diff changeset
61 # define BEGIN_ROUNDING()
359d135f748c Assume 'long double' exists.
Bruno Haible <bruno@clisp.org>
parents: 8535
diff changeset
62 # define END_ROUNDING()
359d135f748c Assume 'long double' exists.
Bruno Haible <bruno@clisp.org>
parents: 8535
diff changeset
63 # define L_(literal) literal
359d135f748c Assume 'long double' exists.
Bruno Haible <bruno@clisp.org>
parents: 8535
diff changeset
64 #endif
8240
536315dcb204 New module 'printf-frexp'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
65
536315dcb204 New module 'printf-frexp'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
66 DOUBLE
9312
bec01fc15c2f Rename parameter 'exp' to 'expptr', to avoid gcc warnings.
Bruno Haible <bruno@clisp.org>
parents: 9309
diff changeset
67 FUNC (DOUBLE x, int *expptr)
8240
536315dcb204 New module 'printf-frexp'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
68 {
536315dcb204 New module 'printf-frexp'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
69 int exponent;
8531
52719799a90e New module 'fpucw'.
Bruno Haible <bruno@clisp.org>
parents: 8362
diff changeset
70 DECL_ROUNDING
52719799a90e New module 'fpucw'.
Bruno Haible <bruno@clisp.org>
parents: 8362
diff changeset
71
52719799a90e New module 'fpucw'.
Bruno Haible <bruno@clisp.org>
parents: 8362
diff changeset
72 BEGIN_ROUNDING ();
8240
536315dcb204 New module 'printf-frexp'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
73
8648
359d135f748c Assume 'long double' exists.
Bruno Haible <bruno@clisp.org>
parents: 8535
diff changeset
74 #ifdef USE_FREXP_LDEXP
8240
536315dcb204 New module 'printf-frexp'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
75 /* frexp and ldexp are usually faster than the loop below. */
536315dcb204 New module 'printf-frexp'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
76 x = FREXP (x, &exponent);
536315dcb204 New module 'printf-frexp'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
77
536315dcb204 New module 'printf-frexp'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
78 x = x + x;
536315dcb204 New module 'printf-frexp'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
79 exponent -= 1;
536315dcb204 New module 'printf-frexp'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
80
536315dcb204 New module 'printf-frexp'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
81 if (exponent < MIN_EXP - 1)
536315dcb204 New module 'printf-frexp'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
82 {
536315dcb204 New module 'printf-frexp'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
83 x = LDEXP (x, exponent - (MIN_EXP - 1));
536315dcb204 New module 'printf-frexp'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
84 exponent = MIN_EXP - 1;
536315dcb204 New module 'printf-frexp'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
85 }
8648
359d135f748c Assume 'long double' exists.
Bruno Haible <bruno@clisp.org>
parents: 8535
diff changeset
86 #else
8535
530583a3b054 Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents: 8531
diff changeset
87 {
530583a3b054 Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents: 8531
diff changeset
88 /* 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
89 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
90 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
91 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
92 int i;
530583a3b054 Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents: 8531
diff changeset
93
530583a3b054 Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents: 8531
diff changeset
94 exponent = 0;
530583a3b054 Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents: 8531
diff changeset
95 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
96 {
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 9312
diff changeset
97 /* A nonnegative exponent. */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 9312
diff changeset
98 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 9312
diff changeset
99 DOUBLE pow2_i; /* = pow2[i] */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 9312
diff changeset
100 DOUBLE powh_i; /* = powh[i] */
8240
536315dcb204 New module 'printf-frexp'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
101
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 9312
diff changeset
102 /* Invariants: pow2_i = 2^2^i, powh_i = 2^-2^i,
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 9312
diff changeset
103 x * 2^exponent = argument, x >= 1.0. */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 9312
diff changeset
104 for (i = 0, pow2_i = L_(2.0), powh_i = L_(0.5);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 9312
diff changeset
105 ;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 9312
diff changeset
106 i++, pow2_i = pow2_i * pow2_i, powh_i = powh_i * powh_i)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 9312
diff changeset
107 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 9312
diff changeset
108 if (x >= pow2_i)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 9312
diff changeset
109 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 9312
diff changeset
110 exponent += (1 << i);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 9312
diff changeset
111 x *= powh_i;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 9312
diff changeset
112 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 9312
diff changeset
113 else
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 9312
diff changeset
114 break;
8535
530583a3b054 Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents: 8531
diff changeset
115
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 9312
diff changeset
116 pow2[i] = pow2_i;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 9312
diff changeset
117 powh[i] = powh_i;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 9312
diff changeset
118 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 9312
diff changeset
119 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 9312
diff changeset
120 /* Here 1.0 <= x < 2^2^i. */
8535
530583a3b054 Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents: 8531
diff changeset
121 }
530583a3b054 Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents: 8531
diff changeset
122 else
8240
536315dcb204 New module 'printf-frexp'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
123 {
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 9312
diff changeset
124 /* A negative exponent. */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 9312
diff changeset
125 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 9312
diff changeset
126 DOUBLE pow2_i; /* = pow2[i] */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 9312
diff changeset
127 DOUBLE powh_i; /* = powh[i] */
8240
536315dcb204 New module 'printf-frexp'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
128
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 9312
diff changeset
129 /* Invariants: pow2_i = 2^2^i, powh_i = 2^-2^i,
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 9312
diff changeset
130 x * 2^exponent = argument, x < 1.0, exponent >= MIN_EXP - 1. */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 9312
diff changeset
131 for (i = 0, pow2_i = L_(2.0), powh_i = L_(0.5);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 9312
diff changeset
132 ;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 9312
diff changeset
133 i++, pow2_i = pow2_i * pow2_i, powh_i = powh_i * powh_i)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 9312
diff changeset
134 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 9312
diff changeset
135 if (exponent - (1 << i) < MIN_EXP - 1)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 9312
diff changeset
136 break;
8535
530583a3b054 Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents: 8531
diff changeset
137
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 9312
diff changeset
138 exponent -= (1 << i);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 9312
diff changeset
139 x *= pow2_i;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 9312
diff changeset
140 if (x >= L_(1.0))
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 9312
diff changeset
141 break;
8535
530583a3b054 Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents: 8531
diff changeset
142
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 9312
diff changeset
143 pow2[i] = pow2_i;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 9312
diff changeset
144 powh[i] = powh_i;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 9312
diff changeset
145 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 9312
diff changeset
146 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 9312
diff changeset
147 /* Here either x < 1.0 and exponent - 2^i < MIN_EXP - 1 <= exponent,
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 9312
diff changeset
148 or 1.0 <= x < 2^2^i and exponent >= MIN_EXP - 1. */
8535
530583a3b054 Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents: 8531
diff changeset
149
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 9312
diff changeset
150 if (x < L_(1.0))
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 9312
diff changeset
151 /* Invariants: x * 2^exponent = argument, x < 1.0 and
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 9312
diff changeset
152 exponent - 2^i < MIN_EXP - 1 <= exponent. */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 9312
diff changeset
153 while (i > 0)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 9312
diff changeset
154 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 9312
diff changeset
155 i--;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 9312
diff changeset
156 if (exponent - (1 << i) >= MIN_EXP - 1)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 9312
diff changeset
157 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 9312
diff changeset
158 exponent -= (1 << i);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 9312
diff changeset
159 x *= pow2[i];
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 9312
diff changeset
160 if (x >= L_(1.0))
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 9312
diff changeset
161 break;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 9312
diff changeset
162 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 9312
diff changeset
163 }
8535
530583a3b054 Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents: 8531
diff changeset
164
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 9312
diff changeset
165 /* Here either x < 1.0 and exponent = MIN_EXP - 1,
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 9312
diff changeset
166 or 1.0 <= x < 2^2^i and exponent >= MIN_EXP - 1. */
8535
530583a3b054 Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents: 8531
diff changeset
167 }
530583a3b054 Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents: 8531
diff changeset
168
530583a3b054 Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents: 8531
diff changeset
169 /* 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
170 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
171 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
172 while (i > 0)
530583a3b054 Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents: 8531
diff changeset
173 {
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 9312
diff changeset
174 i--;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 9312
diff changeset
175 if (x >= pow2[i])
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 9312
diff changeset
176 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 9312
diff changeset
177 exponent += (1 << i);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 9312
diff changeset
178 x *= powh[i];
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 9312
diff changeset
179 }
8240
536315dcb204 New module 'printf-frexp'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
180 }
8535
530583a3b054 Oops, fix ANSI C syntax error introduced in last patch.
Bruno Haible <bruno@clisp.org>
parents: 8531
diff changeset
181 /* 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
182 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
183 }
8648
359d135f748c Assume 'long double' exists.
Bruno Haible <bruno@clisp.org>
parents: 8535
diff changeset
184 #endif
8240
536315dcb204 New module 'printf-frexp'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
185
8531
52719799a90e New module 'fpucw'.
Bruno Haible <bruno@clisp.org>
parents: 8362
diff changeset
186 END_ROUNDING ();
52719799a90e New module 'fpucw'.
Bruno Haible <bruno@clisp.org>
parents: 8362
diff changeset
187
9312
bec01fc15c2f Rename parameter 'exp' to 'expptr', to avoid gcc warnings.
Bruno Haible <bruno@clisp.org>
parents: 9309
diff changeset
188 *expptr = exponent;
8240
536315dcb204 New module 'printf-frexp'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
189 return x;
536315dcb204 New module 'printf-frexp'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
190 }