11414SN/A/* $NetBSD: strtodnrp.c,v 1.2 2008/03/21 23:13:48 christos Exp $ */
21414SN/A
31414SN/A/****************************************************************
41414SN/A
51414SN/AThe author of this software is David M. Gay.
61414SN/A
71414SN/ACopyright (C) 2004 by David M. Gay.
81414SN/AAll Rights Reserved
91414SN/ABased on material in the rest of /netlib/fp/gdota.tar.gz,
101414SN/Awhich is copyright (C) 1998, 2000 by Lucent Technologies.
111414SN/A
121414SN/APermission to use, copy, modify, and distribute this software and
131414SN/Aits documentation for any purpose and without fee is hereby
141414SN/Agranted, provided that the above copyright notice appear in all
151414SN/Acopies and that both that the copyright notice and this
161414SN/Apermission notice and warranty disclaimer appear in supporting
171414SN/Adocumentation, and that the name of Lucent or any of its entities
181414SN/Anot be used in advertising or publicity pertaining to
191414SN/Adistribution of the software without specific, written prior
201414SN/Apermission.
211414SN/A
221414SN/ALUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
2312054SStephen.Hanson@Sun.COMINCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
241414SN/AIN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
251414SN/ASPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
261414SN/AWHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
271414SN/AIN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
281414SN/AARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
291414SN/ATHIS SOFTWARE.
301918SN/A
311414SN/A****************************************************************/
321414SN/A
331414SN/A/* This is a variant of strtod that works on Intel ia32 systems */
341414SN/A/* with the default extended-precision arithmetic -- it does not */
351414SN/A/* require setting the precision control to 53 bits.  */
361414SN/A
371414SN/A/* Please send bug reports to David M. Gay (dmg at acm dot org,
383062Scindi * with " at " changed at "@" and " dot " changed to ".").	*/
393062Scindi
403062Scindi#include "gdtoaimp.h"
413062Scindi
423062Scindi double
433062Scindi#ifdef KR_headers
443062Scindistrtod(s, sp) CONST char *s; char **sp;
453062Scindi#else
463062Scindistrtod(CONST char *s, char **sp)
473062Scindi#endif
483062Scindi{
493062Scindi	static const FPI fpi = { 53, 1-1023-53+1, 2046-1023-53+1, 1, SI };
501414SN/A	ULong bits[2];
511414SN/A	Long expt;
521414SN/A	int k;
531414SN/A	union { ULong L[2]; double d; } u;
548216STarik.Soydan@Sun.COM
551414SN/A	k = strtodg(s, sp, &fpi, &expt, bits);
561414SN/A	if (k == STRTOG_NoMemory) {
571414SN/A		errno = ERANGE;
588216STarik.Soydan@Sun.COM		u.L[0] = Big0;
598216STarik.Soydan@Sun.COM		u.L[1] = Big1;
608216STarik.Soydan@Sun.COM		return u.d;
618216STarik.Soydan@Sun.COM	}
621414SN/A	switch(k & STRTOG_Retmask) {
637987SErwin.Tsaur@Sun.COM	  case STRTOG_NoNumber:
648216STarik.Soydan@Sun.COM	  case STRTOG_Zero:
651865SN/A		u.L[0] = u.L[1] = 0;
661414SN/A		break;
671414SN/A
681414SN/A	  case STRTOG_Normal:
691414SN/A		u.L[_1] = bits[0];
701414SN/A		u.L[_0] = (bits[1] & ~0x100000) | ((expt + 0x3ff + 52) << 20);
711414SN/A		break;
721414SN/A
733895Szx143588	  case STRTOG_Denormal:
743895Szx143588		u.L[_1] = bits[0];
751414SN/A		u.L[_0] = bits[1];
761414SN/A		break;
771414SN/A
781414SN/A	  case STRTOG_Infinite:
791414SN/A		u.L[_0] = 0x7ff00000;
801414SN/A		u.L[_1] = 0;
81		break;
82
83	  case STRTOG_NaN:
84		u.L[0] = d_QNAN0;
85		u.L[1] = d_QNAN1;
86		break;
87
88	  case STRTOG_NaNbits:
89		u.L[_0] = 0x7ff00000 | bits[1];
90		u.L[_1] = bits[0];
91	  }
92	if (k & STRTOG_Neg)
93		u.L[_0] |= 0x80000000L;
94	return u.d;
95	}
96