1*61e56760Schristos /* $NetBSD: strtodnrp.c,v 1.3 2011/03/20 23:15:35 christos Exp $ */
27684d5e0Skleink
37684d5e0Skleink /****************************************************************
47684d5e0Skleink
57684d5e0Skleink The author of this software is David M. Gay.
67684d5e0Skleink
77684d5e0Skleink Copyright (C) 2004 by David M. Gay.
87684d5e0Skleink All Rights Reserved
97684d5e0Skleink Based on material in the rest of /netlib/fp/gdota.tar.gz,
107684d5e0Skleink which is copyright (C) 1998, 2000 by Lucent Technologies.
117684d5e0Skleink
127684d5e0Skleink Permission to use, copy, modify, and distribute this software and
137684d5e0Skleink its documentation for any purpose and without fee is hereby
147684d5e0Skleink granted, provided that the above copyright notice appear in all
157684d5e0Skleink copies and that both that the copyright notice and this
167684d5e0Skleink permission notice and warranty disclaimer appear in supporting
177684d5e0Skleink documentation, and that the name of Lucent or any of its entities
187684d5e0Skleink not be used in advertising or publicity pertaining to
197684d5e0Skleink distribution of the software without specific, written prior
207684d5e0Skleink permission.
217684d5e0Skleink
227684d5e0Skleink LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
237684d5e0Skleink INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
247684d5e0Skleink IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
257684d5e0Skleink SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
267684d5e0Skleink WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
277684d5e0Skleink IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
287684d5e0Skleink ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
297684d5e0Skleink THIS SOFTWARE.
307684d5e0Skleink
317684d5e0Skleink ****************************************************************/
327684d5e0Skleink
337684d5e0Skleink /* This is a variant of strtod that works on Intel ia32 systems */
347684d5e0Skleink /* with the default extended-precision arithmetic -- it does not */
357684d5e0Skleink /* require setting the precision control to 53 bits. */
367684d5e0Skleink
377684d5e0Skleink /* Please send bug reports to David M. Gay (dmg at acm dot org,
387684d5e0Skleink * with " at " changed at "@" and " dot " changed to "."). */
397684d5e0Skleink
407684d5e0Skleink #include "gdtoaimp.h"
417684d5e0Skleink
427684d5e0Skleink double
437684d5e0Skleink #ifdef KR_headers
strtod(s,sp)447684d5e0Skleink strtod(s, sp) CONST char *s; char **sp;
457684d5e0Skleink #else
467684d5e0Skleink strtod(CONST char *s, char **sp)
477684d5e0Skleink #endif
487684d5e0Skleink {
49*61e56760Schristos static const FPI fpi = { 53, 1-1023-53+1, 2046-1023-53+1, 1, SI };
507684d5e0Skleink ULong bits[2];
51*61e56760Schristos Long expt;
527684d5e0Skleink int k;
537684d5e0Skleink union { ULong L[2]; double d; } u;
547684d5e0Skleink
55*61e56760Schristos k = strtodg(s, sp, &fpi, &expt, bits);
56ab625449Schristos if (k == STRTOG_NoMemory) {
57ab625449Schristos errno = ERANGE;
58ab625449Schristos u.L[0] = Big0;
59ab625449Schristos u.L[1] = Big1;
60ab625449Schristos return u.d;
61ab625449Schristos }
627684d5e0Skleink switch(k & STRTOG_Retmask) {
637684d5e0Skleink case STRTOG_NoNumber:
647684d5e0Skleink case STRTOG_Zero:
657684d5e0Skleink u.L[0] = u.L[1] = 0;
667684d5e0Skleink break;
677684d5e0Skleink
687684d5e0Skleink case STRTOG_Normal:
697684d5e0Skleink u.L[_1] = bits[0];
70*61e56760Schristos u.L[_0] = (bits[1] & ~0x100000) | ((expt + 0x3ff + 52) << 20);
717684d5e0Skleink break;
727684d5e0Skleink
737684d5e0Skleink case STRTOG_Denormal:
747684d5e0Skleink u.L[_1] = bits[0];
757684d5e0Skleink u.L[_0] = bits[1];
767684d5e0Skleink break;
777684d5e0Skleink
787684d5e0Skleink case STRTOG_Infinite:
797684d5e0Skleink u.L[_0] = 0x7ff00000;
807684d5e0Skleink u.L[_1] = 0;
817684d5e0Skleink break;
827684d5e0Skleink
837684d5e0Skleink case STRTOG_NaN:
847684d5e0Skleink u.L[0] = d_QNAN0;
857684d5e0Skleink u.L[1] = d_QNAN1;
867684d5e0Skleink break;
877684d5e0Skleink
887684d5e0Skleink case STRTOG_NaNbits:
897684d5e0Skleink u.L[_0] = 0x7ff00000 | bits[1];
907684d5e0Skleink u.L[_1] = bits[0];
917684d5e0Skleink }
927684d5e0Skleink if (k & STRTOG_Neg)
937684d5e0Skleink u.L[_0] |= 0x80000000L;
947684d5e0Skleink return u.d;
957684d5e0Skleink }
96