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 #pragma ident "%Z%%M% %I% %E% SMI" 23 24 /* 25 * Copyright (c) 1988 by Sun Microsystems, Inc. 26 */ 27 28 /* 29 * gcvt - Floating output conversion to minimal length string 30 */ 31 32 #include "base_conversion.h" 33 #ifndef PRE41 34 #include <locale.h> 35 #endif 36 37 void 38 _gcvt(ndigit, pd, trailing, buf) 39 int ndigit; 40 decimal_record *pd; 41 char *buf; 42 { 43 char *p, *pstring; 44 int i; 45 static char *inf8 = "Infinity"; 46 static char *inf3 = "Inf"; 47 static char *nan = "NaN"; 48 #ifdef PRE41 49 char decpt = '.'; 50 #else 51 char decpt = *(localeconv()->decimal_point); 52 #endif 53 54 p = buf; 55 if (pd->sign) 56 *(p++) = '-'; 57 switch (pd->fpclass) { 58 case fp_zero: 59 *(p++) = '0'; 60 if (trailing != 0) { 61 *(p++) = decpt; 62 for (i = 0; i < ndigit - 1; i++) 63 *(p++) = '0'; 64 } 65 break; 66 case fp_infinity: 67 if (ndigit < 8) 68 pstring = inf3; 69 else 70 pstring = inf8; 71 goto copystring; 72 case fp_quiet: 73 case fp_signaling: 74 pstring = nan; 75 copystring: 76 for (i = 0; *pstring != 0;) 77 *(p++) = *(pstring++); 78 break; 79 default: 80 if ((pd->exponent > 0) || (pd->exponent < -(ndigit + 3))) { /* E format. */ 81 char estring[4]; 82 int n; 83 84 i = 0; 85 *(p++) = pd->ds[0]; 86 *(p++) = decpt; 87 for (i = 1; pd->ds[i] != 0;) 88 *(p++) = pd->ds[i++]; 89 if (trailing == 0) { /* Remove trailing zeros and . */ 90 p--; 91 while (*p == '0') 92 p--; 93 if (*p != decpt) 94 p++; 95 } 96 *(p++) = 'e'; 97 n = pd->exponent + i - 1; 98 if (n >= 0) 99 *(p++) = '+'; 100 else { 101 *(p++) = '-'; 102 n = -n; 103 } 104 _fourdigitsquick((short unsigned) n, estring); 105 for (i = 0; estring[i] == '0'; i++); /* Find end of zeros. */ 106 if (i > 2) 107 i = 2; /* Guarantee two zeros. */ 108 for (; i <= 3;) 109 *(p++) = estring[i++]; /* Copy exp digits. */ 110 } else { /* F format. */ 111 if (pd->exponent >= (1 - ndigit)) { /* x.xxx */ 112 for (i = 0; i < (ndigit + pd->exponent);) 113 *(p++) = pd->ds[i++]; 114 *(p++) = decpt; 115 if (pd->ds[i] != 0) { /* More follows point. */ 116 for (; i < ndigit;) 117 *(p++) = pd->ds[i++]; 118 } 119 } else {/* 0.00xxxx */ 120 *(p++) = '0'; 121 *(p++) = decpt; 122 for (i = 0; i < -(pd->exponent + ndigit); i++) 123 *(p++) = '0'; 124 for (i = 0; pd->ds[i] != 0;) 125 *(p++) = pd->ds[i++]; 126 } 127 if (trailing == 0) { /* Remove trailing zeros and point. */ 128 p--; 129 while (*p == '0') 130 p--; 131 if (*p != decpt) 132 p++; 133 } 134 } 135 } 136 *(p++) = 0; 137 } 138 139 char * 140 gconvert(number, ndigit, trailing, buf) 141 double number; 142 int ndigit, trailing; 143 char *buf; 144 { 145 decimal_mode dm; 146 decimal_record dr; 147 fp_exception_field_type fef; 148 149 dm.rd = fp_direction; 150 dm.df = floating_form; 151 dm.ndigits = ndigit; 152 double_to_decimal(&number, &dm, &dr, &fef); 153 _gcvt(ndigit, &dr, trailing, buf); 154 return (buf); 155 } 156 157 char * 158 gcvt(number, ndigit, buf) 159 double number; 160 int ndigit; 161 char *buf; 162 { 163 return (gconvert(number, ndigit, 0, buf)); 164 } 165