]>
git.saurik.com Git - apple/libc.git/blob - stdio/hexfloat.c
51881a90d129881bd17aae8738c75cb6c5fe2f16
2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
27 * hexfloat.c provides routines that vfprintf and vfwprintf can call to convert
28 * floating point numbers to hexidecimal, as used by the %a and %A conversions.
29 * This is necessarily dependent not only on the floating point data format,
30 * but also byte order and existence of long double type.
32 * The union hexdouble represents the IEEE-754 double precision format, while
33 * union hexlongdouble represents the IEEE-754 extended double precision
43 #define EXPSPECIAL 2047
52 unsigned long long fract
:52;
53 #elif defined(__i386__)
54 unsigned long long fract
:52;
58 #error Unsupported architecture
63 #if !__TYPE_LONGDOUBLE_IS_DOUBLE
66 #define LEXPBIAS 16383
67 #define LEXPMIN -16382
68 #define LEXPSPECIAL 32767
74 unsigned long long fract
:63;
81 #endif /* !__TYPE_LONGDOUBLE_IS_DOUBLE */
84 __hdtoa(double d
, const char *xdigs
, int prec
, char *cp
,
85 int *expt
, int *signflag
, char **dtoaend
)
92 //char *start = cp; //DEBUG
95 //printf("\nsign=%d exp=%x fract=%llx\n", u.s.sign, u.s.exp, u.s.fract); //DEBUG
99 case EXPSPECIAL
: /* NaN or Inf */
101 *cp
= (fract
? 'N' : 'I');
103 case 0: /* Zero or denormalized */
105 *expt
= (fract
? EXPMIN
: 0);
107 default: /* Normal numbers */
109 *expt
= u
.s
.exp
- EXPBIAS
;
114 //printf("prec=%d expt=%d\n", prec, *expt); //DEBUG
116 int dig
= (prec
> FRACTHEX
? FRACTHEX
: prec
);
117 int zero
= prec
- dig
;
118 int shift
= FRACTHEX
- dig
;
120 fract
>>= (shift
<< 2);
121 for (hp
= buf
+ dig
, i
= dig
; i
> 0; i
--) {
122 *--hp
= xdigs
[fract
& 0xf];
125 strncpy(cp
, hp
, dig
);
131 //while (start < cp) putchar(*start++); //DEBUG
132 //putchar('\n'); //DEBUG
136 #if !__TYPE_LONGDOUBLE_IS_DOUBLE
139 __hldtoa(long double d
, const char *xdigs
, int prec
, char *cp
,
140 int *expt
, int *signflag
, char **dtoaend
)
142 union hexlongdouble u
;
146 unsigned long long fract
;
147 //char *start = cp; //DEBUG
150 //printf("d=%Lg u.d=%Lg\n", d, u.d); //DEBUG
151 //printf("\nsign=%d exp=%x fract=%llx\n", u.s.sign, u.s.exp, u.s.fract); //DEBUG
152 *signflag
= u
.s
.sign
;
153 fract
= (u
.s
.fract
<< 1);
155 case LEXPSPECIAL
: /* NaN or Inf */
157 *cp
= (fract
? 'N' : 'I');
159 default: /* Normal or denormalized */
160 *cp
++ = u
.s
.i
? '1' : '0';
161 *expt
= u
.s
.exp
- LEXPBIAS
;
166 //printf("prec=%d expt=%d\n", prec, *expt); //DEBUG
168 int dig
= (prec
> LFRACTHEX
? LFRACTHEX
: prec
);
169 int zero
= prec
- dig
;
170 int shift
= LFRACTHEX
- dig
;
172 fract
>>= (shift
<< 2);
173 for (hp
= buf
+ dig
, i
= dig
; i
> 0; i
--) {
174 *--hp
= xdigs
[fract
& 0xf];
177 strncpy(cp
, hp
, dig
);
183 //while (start < cp) putchar(*start++); //DEBUG
184 //putchar('\n'); //DEBUG
187 #endif /* __i386__ */
188 #endif /* !__TYPE_LONGDOUBLE_IS_DOUBLE */
190 #endif /* HEXFLOAT */