10Sstevel@tonic-gate /*
20Sstevel@tonic-gate * CDDL HEADER START
30Sstevel@tonic-gate *
40Sstevel@tonic-gate * The contents of this file are subject to the terms of the
5*6812Sraf * Common Development and Distribution License (the "License").
6*6812Sraf * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate *
80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate * See the License for the specific language governing permissions
110Sstevel@tonic-gate * and limitations under the License.
120Sstevel@tonic-gate *
130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate *
190Sstevel@tonic-gate * CDDL HEADER END
200Sstevel@tonic-gate */
21*6812Sraf
220Sstevel@tonic-gate /*
23*6812Sraf * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
240Sstevel@tonic-gate * Use is subject to license terms.
250Sstevel@tonic-gate */
260Sstevel@tonic-gate
270Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI"
280Sstevel@tonic-gate
29*6812Sraf #include "lint.h"
300Sstevel@tonic-gate #include "base_conversion.h"
310Sstevel@tonic-gate #include <string.h>
320Sstevel@tonic-gate #include <sys/types.h>
330Sstevel@tonic-gate #include "libc.h"
340Sstevel@tonic-gate
350Sstevel@tonic-gate /*
360Sstevel@tonic-gate * Copies the appropriate string for a datum of class cl into *buf,
370Sstevel@tonic-gate * choosing "Inf" or "Infinity" according to ndigits, the desired
380Sstevel@tonic-gate * output string length.
390Sstevel@tonic-gate */
400Sstevel@tonic-gate void
__infnanstring(enum fp_class_type cl,int ndigits,char * buf)410Sstevel@tonic-gate __infnanstring(enum fp_class_type cl, int ndigits, char *buf)
420Sstevel@tonic-gate {
430Sstevel@tonic-gate if (cl == fp_infinity) {
440Sstevel@tonic-gate if (ndigits < 8)
450Sstevel@tonic-gate (void) memcpy(buf, "Inf", 4);
460Sstevel@tonic-gate else
470Sstevel@tonic-gate (void) memcpy(buf, "Infinity", 9);
480Sstevel@tonic-gate __inf_written = 1;
490Sstevel@tonic-gate } else {
500Sstevel@tonic-gate (void) memcpy(buf, "NaN", 4);
510Sstevel@tonic-gate __nan_written = 1;
520Sstevel@tonic-gate }
530Sstevel@tonic-gate }
540Sstevel@tonic-gate
550Sstevel@tonic-gate char *
econvert(double arg,int ndigits,int * decpt,int * sign,char * buf)560Sstevel@tonic-gate econvert(double arg, int ndigits, int *decpt, int *sign, char *buf)
570Sstevel@tonic-gate {
580Sstevel@tonic-gate decimal_mode dm;
590Sstevel@tonic-gate decimal_record dr;
600Sstevel@tonic-gate fp_exception_field_type ef;
610Sstevel@tonic-gate int i;
620Sstevel@tonic-gate
630Sstevel@tonic-gate #if defined(__sparc)
640Sstevel@tonic-gate dm.rd = _QgetRD();
650Sstevel@tonic-gate #elif defined(__i386) || defined(__amd64)
660Sstevel@tonic-gate dm.rd = __xgetRD();
670Sstevel@tonic-gate #else
680Sstevel@tonic-gate #error Unknown architecture
690Sstevel@tonic-gate #endif
700Sstevel@tonic-gate dm.df = floating_form; /* E format. */
710Sstevel@tonic-gate if (ndigits <= 0)
720Sstevel@tonic-gate ndigits = 1;
730Sstevel@tonic-gate else if (ndigits >= DECIMAL_STRING_LENGTH)
740Sstevel@tonic-gate ndigits = DECIMAL_STRING_LENGTH - 1;
750Sstevel@tonic-gate dm.ndigits = ndigits; /* Number of significant digits. */
760Sstevel@tonic-gate double_to_decimal(&arg, &dm, &dr, &ef);
770Sstevel@tonic-gate *sign = dr.sign;
780Sstevel@tonic-gate switch (dr.fpclass) {
790Sstevel@tonic-gate case fp_normal:
800Sstevel@tonic-gate case fp_subnormal:
810Sstevel@tonic-gate *decpt = dr.exponent + ndigits;
820Sstevel@tonic-gate for (i = 0; i < ndigits; i++)
830Sstevel@tonic-gate buf[i] = dr.ds[i];
840Sstevel@tonic-gate buf[ndigits] = 0;
850Sstevel@tonic-gate break;
860Sstevel@tonic-gate case fp_zero:
870Sstevel@tonic-gate *decpt = 1;
880Sstevel@tonic-gate for (i = 0; i < ndigits; i++)
890Sstevel@tonic-gate buf[i] = '0';
900Sstevel@tonic-gate buf[ndigits] = 0;
910Sstevel@tonic-gate break;
920Sstevel@tonic-gate default:
930Sstevel@tonic-gate *decpt = 0;
940Sstevel@tonic-gate __infnanstring(dr.fpclass, ndigits, buf);
950Sstevel@tonic-gate break;
960Sstevel@tonic-gate }
970Sstevel@tonic-gate return (buf);
980Sstevel@tonic-gate }
990Sstevel@tonic-gate
1000Sstevel@tonic-gate char *
seconvert(single * arg,int ndigits,int * decpt,int * sign,char * buf)1010Sstevel@tonic-gate seconvert(single *arg, int ndigits, int *decpt, int *sign, char *buf)
1020Sstevel@tonic-gate {
1030Sstevel@tonic-gate decimal_mode dm;
1040Sstevel@tonic-gate decimal_record dr;
1050Sstevel@tonic-gate fp_exception_field_type ef;
1060Sstevel@tonic-gate int i;
1070Sstevel@tonic-gate
1080Sstevel@tonic-gate #if defined(__sparc)
1090Sstevel@tonic-gate dm.rd = _QgetRD();
1100Sstevel@tonic-gate #elif defined(__i386) || defined(__amd64)
1110Sstevel@tonic-gate dm.rd = __xgetRD();
1120Sstevel@tonic-gate #else
1130Sstevel@tonic-gate #error Unknown architecture
1140Sstevel@tonic-gate #endif
1150Sstevel@tonic-gate dm.df = floating_form; /* E format. */
1160Sstevel@tonic-gate if (ndigits <= 0)
1170Sstevel@tonic-gate ndigits = 1;
1180Sstevel@tonic-gate else if (ndigits >= DECIMAL_STRING_LENGTH)
1190Sstevel@tonic-gate ndigits = DECIMAL_STRING_LENGTH - 1;
1200Sstevel@tonic-gate dm.ndigits = ndigits; /* Number of significant digits. */
1210Sstevel@tonic-gate single_to_decimal(arg, &dm, &dr, &ef);
1220Sstevel@tonic-gate *sign = dr.sign;
1230Sstevel@tonic-gate switch (dr.fpclass) {
1240Sstevel@tonic-gate case fp_normal:
1250Sstevel@tonic-gate case fp_subnormal:
1260Sstevel@tonic-gate *decpt = dr.exponent + ndigits;
1270Sstevel@tonic-gate for (i = 0; i < ndigits; i++)
1280Sstevel@tonic-gate buf[i] = dr.ds[i];
1290Sstevel@tonic-gate buf[ndigits] = 0;
1300Sstevel@tonic-gate break;
1310Sstevel@tonic-gate case fp_zero:
1320Sstevel@tonic-gate *decpt = 1;
1330Sstevel@tonic-gate for (i = 0; i < ndigits; i++)
1340Sstevel@tonic-gate buf[i] = '0';
1350Sstevel@tonic-gate buf[ndigits] = 0;
1360Sstevel@tonic-gate break;
1370Sstevel@tonic-gate default:
1380Sstevel@tonic-gate *decpt = 0;
1390Sstevel@tonic-gate __infnanstring(dr.fpclass, ndigits, buf);
1400Sstevel@tonic-gate break;
1410Sstevel@tonic-gate }
1420Sstevel@tonic-gate return (buf);
1430Sstevel@tonic-gate }
1440Sstevel@tonic-gate
1450Sstevel@tonic-gate char *
qeconvert(quadruple * arg,int ndigits,int * decpt,int * sign,char * buf)1460Sstevel@tonic-gate qeconvert(quadruple *arg, int ndigits, int *decpt, int *sign, char *buf)
1470Sstevel@tonic-gate {
1480Sstevel@tonic-gate decimal_mode dm;
1490Sstevel@tonic-gate decimal_record dr;
1500Sstevel@tonic-gate fp_exception_field_type ef;
1510Sstevel@tonic-gate int i;
1520Sstevel@tonic-gate
1530Sstevel@tonic-gate #if defined(__sparc)
1540Sstevel@tonic-gate dm.rd = _QgetRD();
1550Sstevel@tonic-gate #elif defined(__i386) || defined(__amd64)
1560Sstevel@tonic-gate dm.rd = __xgetRD();
1570Sstevel@tonic-gate #else
1580Sstevel@tonic-gate #error Unknown architecture
1590Sstevel@tonic-gate #endif
1600Sstevel@tonic-gate dm.df = floating_form; /* E format. */
1610Sstevel@tonic-gate if (ndigits <= 0)
1620Sstevel@tonic-gate ndigits = 1;
1630Sstevel@tonic-gate else if (ndigits >= DECIMAL_STRING_LENGTH)
1640Sstevel@tonic-gate ndigits = DECIMAL_STRING_LENGTH - 1;
1650Sstevel@tonic-gate dm.ndigits = ndigits; /* Number of significant digits. */
1660Sstevel@tonic-gate #if defined(__sparc)
1670Sstevel@tonic-gate quadruple_to_decimal(arg, &dm, &dr, &ef);
1680Sstevel@tonic-gate #elif defined(__i386) || defined(__amd64)
1690Sstevel@tonic-gate extended_to_decimal((extended *)arg, &dm, &dr, &ef);
1700Sstevel@tonic-gate #else
1710Sstevel@tonic-gate #error Unknown architecture
1720Sstevel@tonic-gate #endif
1730Sstevel@tonic-gate *sign = dr.sign;
1740Sstevel@tonic-gate switch (dr.fpclass) {
1750Sstevel@tonic-gate case fp_normal:
1760Sstevel@tonic-gate case fp_subnormal:
1770Sstevel@tonic-gate *decpt = dr.exponent + ndigits;
1780Sstevel@tonic-gate for (i = 0; i < ndigits; i++)
1790Sstevel@tonic-gate buf[i] = dr.ds[i];
1800Sstevel@tonic-gate buf[ndigits] = 0;
1810Sstevel@tonic-gate break;
1820Sstevel@tonic-gate case fp_zero:
1830Sstevel@tonic-gate *decpt = 1;
1840Sstevel@tonic-gate for (i = 0; i < ndigits; i++)
1850Sstevel@tonic-gate buf[i] = '0';
1860Sstevel@tonic-gate buf[ndigits] = 0;
1870Sstevel@tonic-gate break;
1880Sstevel@tonic-gate default:
1890Sstevel@tonic-gate *decpt = 0;
1900Sstevel@tonic-gate __infnanstring(dr.fpclass, ndigits, buf);
1910Sstevel@tonic-gate break;
1920Sstevel@tonic-gate }
1930Sstevel@tonic-gate return (buf);
1940Sstevel@tonic-gate }
195