1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* Copyright (c) 1988 AT&T */ 28 /* All Rights Reserved */ 29 30 #pragma ident "%Z%%M% %I% %E% SMI" 31 32 #include "lint.h" 33 #include <errno.h> 34 #include <stdio.h> 35 #include <values.h> 36 #include <floatingpoint.h> 37 #include <stdlib.h> 38 #include <sys/types.h> 39 #include "libc.h" 40 #include "xpg6.h" 41 42 double 43 strtod(const char *cp, char **ptr) 44 { 45 double x; 46 decimal_mode mr; 47 decimal_record dr; 48 fp_exception_field_type fs; 49 enum decimal_string_form form; 50 char *pechar; 51 int lc; 52 53 lc = (__xpg6 & _C99SUSv3_recognize_hexfp)? -1 : 0; 54 string_to_decimal((char **)&cp, MAXINT, lc, &dr, &form, &pechar); 55 if (ptr != NULL) 56 *ptr = (char *)cp; 57 if (form == invalid_form) 58 return (0.0); /* Shameful kluge for SVID's sake. */ 59 #if defined(__sparc) 60 mr.rd = _QgetRD(); 61 #elif defined(__i386) || defined(__amd64) 62 mr.rd = __xgetRD(); 63 #else 64 #error Unknown architecture 65 #endif 66 if ((int)form < 0) 67 __hex_to_double(&dr, mr.rd, &x, &fs); 68 else 69 decimal_to_double(&x, &mr, &dr, &fs); 70 if (fs & ((1 << fp_overflow) | (1 << fp_underflow))) 71 errno = ERANGE; 72 return (x); 73 } 74 75 float 76 strtof(const char *cp, char **ptr) 77 { 78 float x; 79 decimal_mode mr; 80 decimal_record dr; 81 fp_exception_field_type fs; 82 enum decimal_string_form form; 83 char *pechar; 84 85 string_to_decimal((char **)&cp, MAXINT, -1, &dr, &form, &pechar); 86 if (ptr != NULL) 87 *ptr = (char *)cp; 88 if (form == invalid_form) 89 return (0.0f); 90 #if defined(__sparc) 91 mr.rd = _QgetRD(); 92 #elif defined(__i386) || defined(__amd64) 93 mr.rd = __xgetRD(); 94 #else 95 #error Unknown architecture 96 #endif 97 if ((int)form < 0) 98 __hex_to_single(&dr, mr.rd, &x, &fs); 99 else 100 decimal_to_single(&x, &mr, &dr, &fs); 101 if (fs & ((1 << fp_overflow) | (1 << fp_underflow))) 102 errno = ERANGE; 103 return (x); 104 } 105 106 long double 107 strtold(const char *cp, char **ptr) 108 { 109 long double x; 110 decimal_mode mr; 111 decimal_record dr; 112 fp_exception_field_type fs; 113 enum decimal_string_form form; 114 char *pechar; 115 116 string_to_decimal((char **)&cp, MAXINT, -1, &dr, &form, &pechar); 117 if (ptr != NULL) 118 *ptr = (char *)cp; 119 if (form == invalid_form) 120 return (0.0L); 121 #if defined(__sparc) 122 mr.rd = _QgetRD(); 123 if ((int)form < 0) 124 __hex_to_quadruple(&dr, mr.rd, &x, &fs); 125 else 126 decimal_to_quadruple(&x, &mr, &dr, &fs); 127 #elif defined(__i386) || defined(__amd64) 128 mr.rd = __xgetRD(); 129 if ((int)form < 0) 130 __hex_to_extended(&dr, mr.rd, (extended *)&x, &fs); 131 else 132 decimal_to_extended((extended *)&x, &mr, &dr, &fs); 133 #else 134 #error Unknown architecture 135 #endif 136 if (fs & ((1 << fp_overflow) | (1 << fp_underflow))) 137 errno = ERANGE; 138 return (x); 139 } 140