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 2005 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 #pragma weak econvert = _econvert 30 #pragma weak seconvert = _seconvert 31 #pragma weak qeconvert = _qeconvert 32 33 #include "synonyms.h" 34 #include "base_conversion.h" 35 #include <string.h> 36 #include <sys/types.h> 37 #include "libc.h" 38 39 /* 40 * Copies the appropriate string for a datum of class cl into *buf, 41 * choosing "Inf" or "Infinity" according to ndigits, the desired 42 * output string length. 43 */ 44 void 45 __infnanstring(enum fp_class_type cl, int ndigits, char *buf) 46 { 47 if (cl == fp_infinity) { 48 if (ndigits < 8) 49 (void) memcpy(buf, "Inf", 4); 50 else 51 (void) memcpy(buf, "Infinity", 9); 52 __inf_written = 1; 53 } else { 54 (void) memcpy(buf, "NaN", 4); 55 __nan_written = 1; 56 } 57 } 58 59 char * 60 econvert(double arg, int ndigits, int *decpt, int *sign, char *buf) 61 { 62 decimal_mode dm; 63 decimal_record dr; 64 fp_exception_field_type ef; 65 int i; 66 67 #if defined(__sparc) 68 dm.rd = _QgetRD(); 69 #elif defined(__i386) || defined(__amd64) 70 dm.rd = __xgetRD(); 71 #else 72 #error Unknown architecture 73 #endif 74 dm.df = floating_form; /* E format. */ 75 if (ndigits <= 0) 76 ndigits = 1; 77 else if (ndigits >= DECIMAL_STRING_LENGTH) 78 ndigits = DECIMAL_STRING_LENGTH - 1; 79 dm.ndigits = ndigits; /* Number of significant digits. */ 80 double_to_decimal(&arg, &dm, &dr, &ef); 81 *sign = dr.sign; 82 switch (dr.fpclass) { 83 case fp_normal: 84 case fp_subnormal: 85 *decpt = dr.exponent + ndigits; 86 for (i = 0; i < ndigits; i++) 87 buf[i] = dr.ds[i]; 88 buf[ndigits] = 0; 89 break; 90 case fp_zero: 91 *decpt = 1; 92 for (i = 0; i < ndigits; i++) 93 buf[i] = '0'; 94 buf[ndigits] = 0; 95 break; 96 default: 97 *decpt = 0; 98 __infnanstring(dr.fpclass, ndigits, buf); 99 break; 100 } 101 return (buf); 102 } 103 104 char * 105 seconvert(single *arg, int ndigits, int *decpt, int *sign, char *buf) 106 { 107 decimal_mode dm; 108 decimal_record dr; 109 fp_exception_field_type ef; 110 int i; 111 112 #if defined(__sparc) 113 dm.rd = _QgetRD(); 114 #elif defined(__i386) || defined(__amd64) 115 dm.rd = __xgetRD(); 116 #else 117 #error Unknown architecture 118 #endif 119 dm.df = floating_form; /* E format. */ 120 if (ndigits <= 0) 121 ndigits = 1; 122 else if (ndigits >= DECIMAL_STRING_LENGTH) 123 ndigits = DECIMAL_STRING_LENGTH - 1; 124 dm.ndigits = ndigits; /* Number of significant digits. */ 125 single_to_decimal(arg, &dm, &dr, &ef); 126 *sign = dr.sign; 127 switch (dr.fpclass) { 128 case fp_normal: 129 case fp_subnormal: 130 *decpt = dr.exponent + ndigits; 131 for (i = 0; i < ndigits; i++) 132 buf[i] = dr.ds[i]; 133 buf[ndigits] = 0; 134 break; 135 case fp_zero: 136 *decpt = 1; 137 for (i = 0; i < ndigits; i++) 138 buf[i] = '0'; 139 buf[ndigits] = 0; 140 break; 141 default: 142 *decpt = 0; 143 __infnanstring(dr.fpclass, ndigits, buf); 144 break; 145 } 146 return (buf); 147 } 148 149 char * 150 qeconvert(quadruple *arg, int ndigits, int *decpt, int *sign, char *buf) 151 { 152 decimal_mode dm; 153 decimal_record dr; 154 fp_exception_field_type ef; 155 int i; 156 157 #if defined(__sparc) 158 dm.rd = _QgetRD(); 159 #elif defined(__i386) || defined(__amd64) 160 dm.rd = __xgetRD(); 161 #else 162 #error Unknown architecture 163 #endif 164 dm.df = floating_form; /* E format. */ 165 if (ndigits <= 0) 166 ndigits = 1; 167 else if (ndigits >= DECIMAL_STRING_LENGTH) 168 ndigits = DECIMAL_STRING_LENGTH - 1; 169 dm.ndigits = ndigits; /* Number of significant digits. */ 170 #if defined(__sparc) 171 quadruple_to_decimal(arg, &dm, &dr, &ef); 172 #elif defined(__i386) || defined(__amd64) 173 extended_to_decimal((extended *)arg, &dm, &dr, &ef); 174 #else 175 #error Unknown architecture 176 #endif 177 *sign = dr.sign; 178 switch (dr.fpclass) { 179 case fp_normal: 180 case fp_subnormal: 181 *decpt = dr.exponent + ndigits; 182 for (i = 0; i < ndigits; i++) 183 buf[i] = dr.ds[i]; 184 buf[ndigits] = 0; 185 break; 186 case fp_zero: 187 *decpt = 1; 188 for (i = 0; i < ndigits; i++) 189 buf[i] = '0'; 190 buf[ndigits] = 0; 191 break; 192 default: 193 *decpt = 0; 194 __infnanstring(dr.fpclass, ndigits, buf); 195 break; 196 } 197 return (buf); 198 } 199