]>
git.saurik.com Git - apple/libc.git/blob - gdtoa/gdtoa-gethex-fbsd.c
1 /****************************************************************
3 The author of this software is David M. Gay.
5 Copyright (C) 1998 by Lucent Technologies
8 Permission to use, copy, modify, and distribute this software and
9 its documentation for any purpose and without fee is hereby
10 granted, provided that the above copyright notice appear in all
11 copies and that both that the copyright notice and this
12 permission notice and warranty disclaimer appear in supporting
13 documentation, and that the name of Lucent or any of its entities
14 not be used in advertising or publicity pertaining to
15 distribution of the software without specific, written prior
18 LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
19 INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
20 IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
21 SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
22 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
23 IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
24 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
27 ****************************************************************/
29 /* Please send bug reports to David M. Gay (dmg at acm dot org,
30 * with " at " changed at "@" and " dot " changed to "."). */
32 #include "xlocale_private.h"
42 gethex(sp
, fpi
, exp
, bp
, sign
, loc
)
43 CONST
char **sp
; FPI
*fpi
; Long
*exp
; Bigint
**bp
; int sign
; locale_t loc
;
45 gethex( CONST
char **sp
, FPI
*fpi
, Long
*exp
, Bigint
**bp
, int sign
, locale_t loc
)
49 CONST
unsigned char *decpt
, *s0
, *s
, *s1
;
50 int esign
, havedig
, irv
, k
, n
, nbits
, up
, zret
;
51 ULong L
, lostbits
, *x
;
55 unsigned char *decimalpointend
= NULL
;
58 NORMALIZE_LOCALE(loc
);
59 decimalpoint
= localeconv_l(loc
)->decimal_point
;
60 decimalpointlen
= strlen(decimalpoint
);
62 #define decimalpoint '.'
68 s0
= *(CONST
unsigned char **)sp
+ 2;
69 while(s0
[havedig
] == '0')
79 if (strncmp((char *)s
, decimalpoint
, decimalpointlen
) != 0)
80 #else /* USE_LOCALE */
81 if (*s
!= decimalpoint
)
82 #endif /* USE_LOCALE */
85 decpt
= (s
+= decimalpointlen
);
86 decimalpointend
= s
- 1;
87 #else /* USE_LOCALE */
89 #endif /* USE_LOCALE */
102 if (strncmp((char *)s
, decimalpoint
, decimalpointlen
) == 0 && !decpt
)
103 #else /* USE_LOCALE */
104 if (*s
== decimalpoint
&& !decpt
)
105 #endif /* USE_LOCALE */
108 decpt
= (s
+= decimalpointlen
);
109 decimalpointend
= s
- 1;
110 #else /* USE_LOCALE */
112 #endif /* USE_LOCALE */
117 e
= -(((Long
)(s
-decpt
)) << 2);
131 if ((n
= hexdig
[*s
]) == 0 || n
> 0x19) {
136 while((n
= hexdig
[*++s
]) !=0 && n
<= 0x19)
137 e1
= 10*e1
+ n
- 0x10;
144 return havedig
? STRTOG_Zero
: STRTOG_NoNumber
;
146 for(k
= 0; n
> 7; n
>>= 1)
154 if (--s1
== decimalpointend
) {
155 s1
-= decimalpointlen
- 1;
158 #else /* USE_LOCALE */
159 if (*--s1
== decimalpoint
)
161 #endif /* USE_LOCALE */
167 L
|= (hexdig
[*s1
] & 0x0f) << n
;
171 b
->wds
= n
= x
- b
->x
;
172 n
= 32*n
- hi0bits(L
);
181 if (x
[k
>>kshift
] & 1 << (k
& kmask
)) {
183 if (k
> 1 && any_on(b
,k
-1))
190 else if (n
< nbits
) {
200 return STRTOG_Infinite
| STRTOG_Overflow
| STRTOG_Inexhi
;
204 irv
= STRTOG_Denormal
;
207 switch (fpi
->rounding
) {
209 if (n
== nbits
&& (n
< 2 || any_on(b
,n
-1)))
222 return STRTOG_Denormal
| STRTOG_Inexhi
228 return STRTOG_Zero
| STRTOG_Inexlo
| STRTOG_Underflow
;
234 lostbits
= any_on(b
,k
);
235 if (x
[k
>>kshift
] & 1 << (k
& kmask
))
243 switch(fpi
->rounding
) {
248 && (lostbits
& 1) | x
[0] & 1)
261 if (irv
== STRTOG_Denormal
) {
262 if (nbits
== fpi
->nbits
- 1
263 && x
[nbits
>> kshift
] & 1 << (nbits
& kmask
))
267 || (n
= nbits
& kmask
) !=0
268 && hi0bits(x
[k
-1]) < 32-n
) {
273 irv
|= STRTOG_Inexhi
;
276 irv
|= STRTOG_Inexlo
;