xref: /freebsd-src/contrib/gdtoa/strtodnrp.c (revision c88250a57d53dba5de2e77508383019ff63e88b6)
1*c88250a5SDavid Schultz /****************************************************************
2*c88250a5SDavid Schultz 
3*c88250a5SDavid Schultz The author of this software is David M. Gay.
4*c88250a5SDavid Schultz 
5*c88250a5SDavid Schultz Copyright (C) 2004 by David M. Gay.
6*c88250a5SDavid Schultz All Rights Reserved
7*c88250a5SDavid Schultz Based on material in the rest of /netlib/fp/gdota.tar.gz,
8*c88250a5SDavid Schultz which is copyright (C) 1998, 2000 by Lucent Technologies.
9*c88250a5SDavid Schultz 
10*c88250a5SDavid Schultz Permission to use, copy, modify, and distribute this software and
11*c88250a5SDavid Schultz its documentation for any purpose and without fee is hereby
12*c88250a5SDavid Schultz granted, provided that the above copyright notice appear in all
13*c88250a5SDavid Schultz copies and that both that the copyright notice and this
14*c88250a5SDavid Schultz permission notice and warranty disclaimer appear in supporting
15*c88250a5SDavid Schultz documentation, and that the name of Lucent or any of its entities
16*c88250a5SDavid Schultz not be used in advertising or publicity pertaining to
17*c88250a5SDavid Schultz distribution of the software without specific, written prior
18*c88250a5SDavid Schultz permission.
19*c88250a5SDavid Schultz 
20*c88250a5SDavid Schultz LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
21*c88250a5SDavid Schultz INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
22*c88250a5SDavid Schultz IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
23*c88250a5SDavid Schultz SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
24*c88250a5SDavid Schultz WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
25*c88250a5SDavid Schultz IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
26*c88250a5SDavid Schultz ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
27*c88250a5SDavid Schultz THIS SOFTWARE.
28*c88250a5SDavid Schultz 
29*c88250a5SDavid Schultz ****************************************************************/
30*c88250a5SDavid Schultz 
31*c88250a5SDavid Schultz /* This is a variant of strtod that works on Intel ia32 systems */
32*c88250a5SDavid Schultz /* with the default extended-precision arithmetic -- it does not */
33*c88250a5SDavid Schultz /* require setting the precision control to 53 bits.  */
34*c88250a5SDavid Schultz 
35*c88250a5SDavid Schultz /* Please send bug reports to David M. Gay (dmg at acm dot org,
36*c88250a5SDavid Schultz  * with " at " changed at "@" and " dot " changed to ".").	*/
37*c88250a5SDavid Schultz 
38*c88250a5SDavid Schultz #include "gdtoaimp.h"
39*c88250a5SDavid Schultz 
40*c88250a5SDavid Schultz  double
41*c88250a5SDavid Schultz #ifdef KR_headers
strtod(s,sp)42*c88250a5SDavid Schultz strtod(s, sp) CONST char *s; char **sp;
43*c88250a5SDavid Schultz #else
44*c88250a5SDavid Schultz strtod(CONST char *s, char **sp)
45*c88250a5SDavid Schultz #endif
46*c88250a5SDavid Schultz {
47*c88250a5SDavid Schultz 	static FPI fpi = { 53, 1-1023-53+1, 2046-1023-53+1, 1, SI };
48*c88250a5SDavid Schultz 	ULong bits[2];
49*c88250a5SDavid Schultz 	Long exp;
50*c88250a5SDavid Schultz 	int k;
51*c88250a5SDavid Schultz 	union { ULong L[2]; double d; } u;
52*c88250a5SDavid Schultz 
53*c88250a5SDavid Schultz 	k = strtodg(s, sp, &fpi, &exp, bits);
54*c88250a5SDavid Schultz 	switch(k & STRTOG_Retmask) {
55*c88250a5SDavid Schultz 	  case STRTOG_NoNumber:
56*c88250a5SDavid Schultz 	  case STRTOG_Zero:
57*c88250a5SDavid Schultz 		u.L[0] = u.L[1] = 0;
58*c88250a5SDavid Schultz 		break;
59*c88250a5SDavid Schultz 
60*c88250a5SDavid Schultz 	  case STRTOG_Normal:
61*c88250a5SDavid Schultz 		u.L[_1] = bits[0];
62*c88250a5SDavid Schultz 		u.L[_0] = (bits[1] & ~0x100000) | ((exp + 0x3ff + 52) << 20);
63*c88250a5SDavid Schultz 		break;
64*c88250a5SDavid Schultz 
65*c88250a5SDavid Schultz 	  case STRTOG_Denormal:
66*c88250a5SDavid Schultz 		u.L[_1] = bits[0];
67*c88250a5SDavid Schultz 		u.L[_0] = bits[1];
68*c88250a5SDavid Schultz 		break;
69*c88250a5SDavid Schultz 
70*c88250a5SDavid Schultz 	  case STRTOG_Infinite:
71*c88250a5SDavid Schultz 		u.L[_0] = 0x7ff00000;
72*c88250a5SDavid Schultz 		u.L[_1] = 0;
73*c88250a5SDavid Schultz 		break;
74*c88250a5SDavid Schultz 
75*c88250a5SDavid Schultz 	  case STRTOG_NaN:
76*c88250a5SDavid Schultz 		u.L[0] = d_QNAN0;
77*c88250a5SDavid Schultz 		u.L[1] = d_QNAN1;
78*c88250a5SDavid Schultz 		break;
79*c88250a5SDavid Schultz 
80*c88250a5SDavid Schultz 	  case STRTOG_NaNbits:
81*c88250a5SDavid Schultz 		u.L[_0] = 0x7ff00000 | bits[1];
82*c88250a5SDavid Schultz 		u.L[_1] = bits[0];
83*c88250a5SDavid Schultz 	  }
84*c88250a5SDavid Schultz 	if (k & STRTOG_Neg)
85*c88250a5SDavid Schultz 		u.L[_0] |= 0x80000000L;
86*c88250a5SDavid Schultz 	return u.d;
87*c88250a5SDavid Schultz 	}
88