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