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