]>
git.saurik.com Git - apple/libc.git/blob - stdio/hexfloat.c
2e59d9eea2d0612aa4481d16ab30c77401e90ae0
2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
23 * @APPLE_LICENSE_HEADER_END@
29 * hexfloat.c provides routines that vfprintf and vfwprintf can call to convert
30 * floating point numbers to hexidecimal, as used by the %a and %A conversions.
31 * This is necessarily dependent not only on the floating point data format,
32 * but also byte order and existence of long double type.
34 * The union hexdouble represents the IEEE-754 double precision format, while
35 * union hexlongdouble represents the IEEE-754 extended double precision
45 #define EXPSPECIAL 2047
54 unsigned long long fract
:52;
55 #elif defined(__i386__)
56 unsigned long long fract
:52;
60 #error Unsupported architecture
65 #if !__TYPE_LONGDOUBLE_IS_DOUBLE
68 #define LEXPBIAS 16383
69 #define LEXPMIN -16382
70 #define LEXPSPECIAL 32767
76 unsigned long long fract
:63;
83 #endif /* !__TYPE_LONGDOUBLE_IS_DOUBLE */
86 __hdtoa(double d
, const char *xdigs
, int prec
, char *cp
,
87 int *expt
, int *signflag
, char **dtoaend
)
94 //char *start = cp; //DEBUG
97 //printf("\nsign=%d exp=%x fract=%llx\n", u.s.sign, u.s.exp, u.s.fract); //DEBUG
101 case EXPSPECIAL
: /* NaN or Inf */
103 *cp
= (fract
? 'N' : 'I');
105 case 0: /* Zero or denormalized */
107 *expt
= (fract
? EXPMIN
: 0);
109 default: /* Normal numbers */
111 *expt
= u
.s
.exp
- EXPBIAS
;
116 //printf("prec=%d expt=%d\n", prec, *expt); //DEBUG
118 int dig
= (prec
> FRACTHEX
? FRACTHEX
: prec
);
119 int zero
= prec
- dig
;
120 int shift
= FRACTHEX
- dig
;
122 fract
>>= (shift
<< 2);
123 for (hp
= buf
+ dig
, i
= dig
; i
> 0; i
--) {
124 *--hp
= xdigs
[fract
& 0xf];
127 strncpy(cp
, hp
, dig
);
133 //while (start < cp) putchar(*start++); //DEBUG
134 //putchar('\n'); //DEBUG
138 #if !__TYPE_LONGDOUBLE_IS_DOUBLE
141 __hldtoa(long double d
, const char *xdigs
, int prec
, char *cp
,
142 int *expt
, int *signflag
, char **dtoaend
)
144 union hexlongdouble u
;
148 unsigned long long fract
;
149 //char *start = cp; //DEBUG
152 //printf("d=%Lg u.d=%Lg\n", d, u.d); //DEBUG
153 //printf("\nsign=%d exp=%x fract=%llx\n", u.s.sign, u.s.exp, u.s.fract); //DEBUG
154 *signflag
= u
.s
.sign
;
155 fract
= (u
.s
.fract
<< 1);
157 case LEXPSPECIAL
: /* NaN or Inf */
159 *cp
= (fract
? 'N' : 'I');
161 default: /* Normal or denormalized */
162 *cp
++ = u
.s
.i
? '1' : '0';
163 *expt
= u
.s
.exp
- LEXPBIAS
;
168 //printf("prec=%d expt=%d\n", prec, *expt); //DEBUG
170 int dig
= (prec
> LFRACTHEX
? LFRACTHEX
: prec
);
171 int zero
= prec
- dig
;
172 int shift
= LFRACTHEX
- dig
;
174 fract
>>= (shift
<< 2);
175 for (hp
= buf
+ dig
, i
= dig
; i
> 0; i
--) {
176 *--hp
= xdigs
[fract
& 0xf];
179 strncpy(cp
, hp
, dig
);
185 //while (start < cp) putchar(*start++); //DEBUG
186 //putchar('\n'); //DEBUG
189 #endif /* __i386__ */
190 #endif /* !__TYPE_LONGDOUBLE_IS_DOUBLE */
192 #endif /* HEXFLOAT */