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 #include "lint.h" 31 #include <errno.h> 32 #include <stdio.h> 33 #include <values.h> 34 #include <floatingpoint.h> 35 #include <stdlib.h> 36 #include <sys/types.h> 37 #include "libc.h" 38 #include "xpg6.h" 39 40 double 41 strtod(const char *cp, char **ptr) 42 { 43 double x; 44 decimal_mode mr; 45 decimal_record dr; 46 fp_exception_field_type fs; 47 enum decimal_string_form form; 48 char *pechar; 49 int lc; 50 51 lc = (__xpg6 & _C99SUSv3_recognize_hexfp)? -1 : 0; 52 string_to_decimal((char **)&cp, MAXINT, lc, &dr, &form, &pechar); 53 if (ptr != NULL) 54 *ptr = (char *)cp; 55 if (form == invalid_form) 56 return (0.0); /* Shameful kluge for SVID's sake. */ 57 #if defined(__sparc) 58 mr.rd = _QgetRD(); 59 #elif defined(__i386) || defined(__amd64) 60 mr.rd = __xgetRD(); 61 #else 62 #error Unknown architecture 63 #endif 64 if ((int)form < 0) 65 __hex_to_double(&dr, mr.rd, &x, &fs); 66 else 67 decimal_to_double(&x, &mr, &dr, &fs); 68 if (fs & ((1 << fp_overflow) | (1 << fp_underflow))) 69 errno = ERANGE; 70 return (x); 71 } 72 73 float 74 strtof(const char *cp, char **ptr) 75 { 76 float x; 77 decimal_mode mr; 78 decimal_record dr; 79 fp_exception_field_type fs; 80 enum decimal_string_form form; 81 char *pechar; 82 83 string_to_decimal((char **)&cp, MAXINT, -1, &dr, &form, &pechar); 84 if (ptr != NULL) 85 *ptr = (char *)cp; 86 if (form == invalid_form) 87 return (0.0f); 88 #if defined(__sparc) 89 mr.rd = _QgetRD(); 90 #elif defined(__i386) || defined(__amd64) 91 mr.rd = __xgetRD(); 92 #else 93 #error Unknown architecture 94 #endif 95 if ((int)form < 0) 96 __hex_to_single(&dr, mr.rd, &x, &fs); 97 else 98 decimal_to_single(&x, &mr, &dr, &fs); 99 if (fs & ((1 << fp_overflow) | (1 << fp_underflow))) 100 errno = ERANGE; 101 return (x); 102 } 103 104 long double 105 strtold(const char *cp, char **ptr) 106 { 107 long double x; 108 decimal_mode mr; 109 decimal_record dr; 110 fp_exception_field_type fs; 111 enum decimal_string_form form; 112 char *pechar; 113 114 string_to_decimal((char **)&cp, MAXINT, -1, &dr, &form, &pechar); 115 if (ptr != NULL) 116 *ptr = (char *)cp; 117 if (form == invalid_form) 118 return (0.0L); 119 #if defined(__sparc) 120 mr.rd = _QgetRD(); 121 if ((int)form < 0) 122 __hex_to_quadruple(&dr, mr.rd, &x, &fs); 123 else 124 decimal_to_quadruple(&x, &mr, &dr, &fs); 125 #elif defined(__i386) || defined(__amd64) 126 mr.rd = __xgetRD(); 127 if ((int)form < 0) 128 __hex_to_extended(&dr, mr.rd, (extended *)&x, &fs); 129 else 130 decimal_to_extended((extended *)&x, &mr, &dr, &fs); 131 #else 132 #error Unknown architecture 133 #endif 134 if (fs & ((1 << fp_overflow) | (1 << fp_underflow))) 135 errno = ERANGE; 136 return (x); 137 } 138