Home | History | Annotate | Download | only in common
      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