1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 25*7c478bd9Sstevel@tonic-gate */ 26*7c478bd9Sstevel@tonic-gate 27*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 28*7c478bd9Sstevel@tonic-gate 29*7c478bd9Sstevel@tonic-gate /* 30*7c478bd9Sstevel@tonic-gate * Short cut for conversion from double precision to decimal 31*7c478bd9Sstevel@tonic-gate * floating point 32*7c478bd9Sstevel@tonic-gate */ 33*7c478bd9Sstevel@tonic-gate 34*7c478bd9Sstevel@tonic-gate #include "synonyms.h" 35*7c478bd9Sstevel@tonic-gate #include <sys/types.h> 36*7c478bd9Sstevel@tonic-gate #include <sys/isa_defs.h> 37*7c478bd9Sstevel@tonic-gate #include "base_conversion.h" 38*7c478bd9Sstevel@tonic-gate 39*7c478bd9Sstevel@tonic-gate /* 40*7c478bd9Sstevel@tonic-gate * Powers of ten rounded up. If i is the largest index such that 41*7c478bd9Sstevel@tonic-gate * tbl_decade[i] <= x, then: 42*7c478bd9Sstevel@tonic-gate * 43*7c478bd9Sstevel@tonic-gate * if i == 0 then x < 10^-49 44*7c478bd9Sstevel@tonic-gate * else if i == TBL_DECADE_MAX then x >= 10^67 45*7c478bd9Sstevel@tonic-gate * else 10^(i-TBL_DECADE_OFFSET) <= x < 10^(i-TBL_DECADE_OFFSET+1) 46*7c478bd9Sstevel@tonic-gate */ 47*7c478bd9Sstevel@tonic-gate 48*7c478bd9Sstevel@tonic-gate #define TBL_DECADE_OFFSET 50 49*7c478bd9Sstevel@tonic-gate #define TBL_DECADE_MAX 117 50*7c478bd9Sstevel@tonic-gate 51*7c478bd9Sstevel@tonic-gate static const double tbl_decade[TBL_DECADE_MAX + 1] = { 52*7c478bd9Sstevel@tonic-gate 0.0, 53*7c478bd9Sstevel@tonic-gate 1.00000000000000012631e-49, 1.00000000000000012631e-48, 54*7c478bd9Sstevel@tonic-gate 1.00000000000000009593e-47, 1.00000000000000002300e-46, 55*7c478bd9Sstevel@tonic-gate 1.00000000000000013968e-45, 1.00000000000000007745e-44, 56*7c478bd9Sstevel@tonic-gate 1.00000000000000007745e-43, 1.00000000000000003762e-42, 57*7c478bd9Sstevel@tonic-gate 1.00000000000000000576e-41, 1.00000000000000013321e-40, 58*7c478bd9Sstevel@tonic-gate 1.00000000000000009243e-39, 1.00000000000000009243e-38, 59*7c478bd9Sstevel@tonic-gate 1.00000000000000006632e-37, 1.00000000000000010809e-36, 60*7c478bd9Sstevel@tonic-gate 1.00000000000000000786e-35, 1.00000000000000014150e-34, 61*7c478bd9Sstevel@tonic-gate 1.00000000000000005597e-33, 1.00000000000000005597e-32, 62*7c478bd9Sstevel@tonic-gate 1.00000000000000008334e-31, 1.00000000000000008334e-30, 63*7c478bd9Sstevel@tonic-gate 1.00000000000000008334e-29, 1.00000000000000008334e-28, 64*7c478bd9Sstevel@tonic-gate 1.00000000000000003849e-27, 1.00000000000000003849e-26, 65*7c478bd9Sstevel@tonic-gate 1.00000000000000003849e-25, 1.00000000000000010737e-24, 66*7c478bd9Sstevel@tonic-gate 1.00000000000000010737e-23, 1.00000000000000004860e-22, 67*7c478bd9Sstevel@tonic-gate 1.00000000000000009562e-21, 1.00000000000000009562e-20, 68*7c478bd9Sstevel@tonic-gate 1.00000000000000009562e-19, 1.00000000000000007154e-18, 69*7c478bd9Sstevel@tonic-gate 1.00000000000000007154e-17, 1.00000000000000010236e-16, 70*7c478bd9Sstevel@tonic-gate 1.00000000000000007771e-15, 1.00000000000000015659e-14, 71*7c478bd9Sstevel@tonic-gate 1.00000000000000003037e-13, 1.00000000000000018184e-12, 72*7c478bd9Sstevel@tonic-gate 1.00000000000000010106e-11, 1.00000000000000003643e-10, 73*7c478bd9Sstevel@tonic-gate 1.00000000000000006228e-09, 1.00000000000000002092e-08, 74*7c478bd9Sstevel@tonic-gate 1.00000000000000008710e-07, 1.00000000000000016651e-06, 75*7c478bd9Sstevel@tonic-gate 1.00000000000000008180e-05, 1.00000000000000004792e-04, 76*7c478bd9Sstevel@tonic-gate 1.00000000000000002082e-03, 1.00000000000000002082e-02, 77*7c478bd9Sstevel@tonic-gate 1.00000000000000005551e-01, 1.00000000000000000000e+00, 78*7c478bd9Sstevel@tonic-gate 1.00000000000000000000e+01, 1.00000000000000000000e+02, 79*7c478bd9Sstevel@tonic-gate 1.00000000000000000000e+03, 1.00000000000000000000e+04, 80*7c478bd9Sstevel@tonic-gate 1.00000000000000000000e+05, 1.00000000000000000000e+06, 81*7c478bd9Sstevel@tonic-gate 1.00000000000000000000e+07, 1.00000000000000000000e+08, 82*7c478bd9Sstevel@tonic-gate 1.00000000000000000000e+09, 1.00000000000000000000e+10, 83*7c478bd9Sstevel@tonic-gate 1.00000000000000000000e+11, 1.00000000000000000000e+12, 84*7c478bd9Sstevel@tonic-gate 1.00000000000000000000e+13, 1.00000000000000000000e+14, 85*7c478bd9Sstevel@tonic-gate 1.00000000000000000000e+15, 1.00000000000000000000e+16, 86*7c478bd9Sstevel@tonic-gate 1.00000000000000000000e+17, 1.00000000000000000000e+18, 87*7c478bd9Sstevel@tonic-gate 1.00000000000000000000e+19, 1.00000000000000000000e+20, 88*7c478bd9Sstevel@tonic-gate 1.00000000000000000000e+21, 1.00000000000000000000e+22, 89*7c478bd9Sstevel@tonic-gate 1.00000000000000008389e+23, 1.00000000000000011744e+24, 90*7c478bd9Sstevel@tonic-gate 1.00000000000000009060e+25, 1.00000000000000004765e+26, 91*7c478bd9Sstevel@tonic-gate 1.00000000000000001329e+27, 1.00000000000000017821e+28, 92*7c478bd9Sstevel@tonic-gate 1.00000000000000009025e+29, 1.00000000000000001988e+30, 93*7c478bd9Sstevel@tonic-gate 1.00000000000000007618e+31, 1.00000000000000005366e+32, 94*7c478bd9Sstevel@tonic-gate 1.00000000000000008969e+33, 1.00000000000000006087e+34, 95*7c478bd9Sstevel@tonic-gate 1.00000000000000015310e+35, 1.00000000000000004242e+36, 96*7c478bd9Sstevel@tonic-gate 1.00000000000000007194e+37, 1.00000000000000016638e+38, 97*7c478bd9Sstevel@tonic-gate 1.00000000000000009082e+39, 1.00000000000000003038e+40, 98*7c478bd9Sstevel@tonic-gate 1.00000000000000000620e+41, 1.00000000000000004489e+42, 99*7c478bd9Sstevel@tonic-gate 1.00000000000000001394e+43, 1.00000000000000008821e+44, 100*7c478bd9Sstevel@tonic-gate 1.00000000000000008821e+45, 1.00000000000000011990e+46, 101*7c478bd9Sstevel@tonic-gate 1.00000000000000004385e+47, 1.00000000000000004385e+48, 102*7c478bd9Sstevel@tonic-gate 1.00000000000000007630e+49, 1.00000000000000007630e+50, 103*7c478bd9Sstevel@tonic-gate 1.00000000000000015937e+51, 1.00000000000000012614e+52, 104*7c478bd9Sstevel@tonic-gate 1.00000000000000020590e+53, 1.00000000000000007829e+54, 105*7c478bd9Sstevel@tonic-gate 1.00000000000000001024e+55, 1.00000000000000009190e+56, 106*7c478bd9Sstevel@tonic-gate 1.00000000000000004835e+57, 1.00000000000000008319e+58, 107*7c478bd9Sstevel@tonic-gate 1.00000000000000008319e+59, 1.00000000000000012779e+60, 108*7c478bd9Sstevel@tonic-gate 1.00000000000000009211e+61, 1.00000000000000003502e+62, 109*7c478bd9Sstevel@tonic-gate 1.00000000000000005786e+63, 1.00000000000000002132e+64, 110*7c478bd9Sstevel@tonic-gate 1.00000000000000010901e+65, 1.00000000000000013239e+66, 111*7c478bd9Sstevel@tonic-gate 1.00000000000000013239e+67 112*7c478bd9Sstevel@tonic-gate }; 113*7c478bd9Sstevel@tonic-gate 114*7c478bd9Sstevel@tonic-gate /* 115*7c478bd9Sstevel@tonic-gate * Convert a positive double precision integer x <= 2147483647999999744 116*7c478bd9Sstevel@tonic-gate * (the largest double less than 2^31 * 10^9; this implementation works 117*7c478bd9Sstevel@tonic-gate * up to the largest double less than 2^25 * 10^12) to a string of ASCII 118*7c478bd9Sstevel@tonic-gate * decimal digits, adding leading zeroes so that the result has at least 119*7c478bd9Sstevel@tonic-gate * n digits. The string is terminated by a null byte, and its length 120*7c478bd9Sstevel@tonic-gate * is returned. 121*7c478bd9Sstevel@tonic-gate * 122*7c478bd9Sstevel@tonic-gate * This routine assumes round-to-nearest mode is in effect and any 123*7c478bd9Sstevel@tonic-gate * exceptions raised will be ignored. 124*7c478bd9Sstevel@tonic-gate */ 125*7c478bd9Sstevel@tonic-gate 126*7c478bd9Sstevel@tonic-gate #define tenm4 tbl_decade[TBL_DECADE_OFFSET - 4] 127*7c478bd9Sstevel@tonic-gate #define ten4 tbl_decade[TBL_DECADE_OFFSET + 4] 128*7c478bd9Sstevel@tonic-gate #define tenm12 tbl_decade[TBL_DECADE_OFFSET - 12] 129*7c478bd9Sstevel@tonic-gate #define ten12 tbl_decade[TBL_DECADE_OFFSET + 12] 130*7c478bd9Sstevel@tonic-gate #define one tbl_decade[TBL_DECADE_OFFSET] 131*7c478bd9Sstevel@tonic-gate 132*7c478bd9Sstevel@tonic-gate static int 133*7c478bd9Sstevel@tonic-gate __double_to_digits(double x, char *s, int n) 134*7c478bd9Sstevel@tonic-gate { 135*7c478bd9Sstevel@tonic-gate double y; 136*7c478bd9Sstevel@tonic-gate int d[5], i, j; 137*7c478bd9Sstevel@tonic-gate char *ss, tmp[4]; 138*7c478bd9Sstevel@tonic-gate 139*7c478bd9Sstevel@tonic-gate /* decompose x into four-digit chunks */ 140*7c478bd9Sstevel@tonic-gate y = (int)(x * tenm12); 141*7c478bd9Sstevel@tonic-gate x -= y * ten12; 142*7c478bd9Sstevel@tonic-gate if (x < 0.0) { 143*7c478bd9Sstevel@tonic-gate y -= one; 144*7c478bd9Sstevel@tonic-gate x += ten12; 145*7c478bd9Sstevel@tonic-gate } 146*7c478bd9Sstevel@tonic-gate d[0] = (int)(y * tenm4); 147*7c478bd9Sstevel@tonic-gate d[1] = (int)(y - d[0] * ten4); 148*7c478bd9Sstevel@tonic-gate y = (int)(x * tenm4); 149*7c478bd9Sstevel@tonic-gate d[4] = (int)(x - y * ten4); 150*7c478bd9Sstevel@tonic-gate d[2] = (int)(y * tenm4); 151*7c478bd9Sstevel@tonic-gate d[3] = (int)(y - d[2] * ten4); 152*7c478bd9Sstevel@tonic-gate 153*7c478bd9Sstevel@tonic-gate /* 154*7c478bd9Sstevel@tonic-gate * Find the first nonzero chunk or the point at which to start 155*7c478bd9Sstevel@tonic-gate * converting so we have n digits, whichever comes first. 156*7c478bd9Sstevel@tonic-gate */ 157*7c478bd9Sstevel@tonic-gate ss = s; 158*7c478bd9Sstevel@tonic-gate if (n > 20) { 159*7c478bd9Sstevel@tonic-gate for (j = 0; j < n - 20; j++) 160*7c478bd9Sstevel@tonic-gate *ss++ = '0'; 161*7c478bd9Sstevel@tonic-gate i = 0; 162*7c478bd9Sstevel@tonic-gate } else { 163*7c478bd9Sstevel@tonic-gate for (i = 0; d[i] == 0 && n <= ((4 - i) << 2); i++) 164*7c478bd9Sstevel@tonic-gate ; 165*7c478bd9Sstevel@tonic-gate __four_digits_quick(d[i], tmp); 166*7c478bd9Sstevel@tonic-gate for (j = 0; tmp[j] == '0' && n <= ((4 - i) << 2) + 3 - j; j++) 167*7c478bd9Sstevel@tonic-gate ; 168*7c478bd9Sstevel@tonic-gate while (j < 4) 169*7c478bd9Sstevel@tonic-gate *ss++ = tmp[j++]; 170*7c478bd9Sstevel@tonic-gate i++; 171*7c478bd9Sstevel@tonic-gate } 172*7c478bd9Sstevel@tonic-gate 173*7c478bd9Sstevel@tonic-gate /* continue converting four-digit chunks */ 174*7c478bd9Sstevel@tonic-gate while (i < 5) { 175*7c478bd9Sstevel@tonic-gate __four_digits_quick(d[i], ss); 176*7c478bd9Sstevel@tonic-gate ss += 4; 177*7c478bd9Sstevel@tonic-gate i++; 178*7c478bd9Sstevel@tonic-gate } 179*7c478bd9Sstevel@tonic-gate 180*7c478bd9Sstevel@tonic-gate *ss = '\0'; 181*7c478bd9Sstevel@tonic-gate return (ss - s); 182*7c478bd9Sstevel@tonic-gate } 183*7c478bd9Sstevel@tonic-gate 184*7c478bd9Sstevel@tonic-gate /* 185*7c478bd9Sstevel@tonic-gate * Round a positive double precision number *x to the nearest integer, 186*7c478bd9Sstevel@tonic-gate * returning the result and passing back an indication of accuracy in 187*7c478bd9Sstevel@tonic-gate * *pe. On entry, nrx is the number of rounding errors already com- 188*7c478bd9Sstevel@tonic-gate * mitted in forming *x. On exit, *pe is 0 if *x was already integral 189*7c478bd9Sstevel@tonic-gate * and exact, 1 if the result is the correctly rounded integer value 190*7c478bd9Sstevel@tonic-gate * but not exact, and 2 if error in *x precludes determining the cor- 191*7c478bd9Sstevel@tonic-gate * rectly rounded integer value (i.e., the error might be larger than 192*7c478bd9Sstevel@tonic-gate * 1/2 - |*x - rx|, where rx is the nearest integer to *x). 193*7c478bd9Sstevel@tonic-gate */ 194*7c478bd9Sstevel@tonic-gate 195*7c478bd9Sstevel@tonic-gate static union { 196*7c478bd9Sstevel@tonic-gate unsigned int i[2]; 197*7c478bd9Sstevel@tonic-gate double d; 198*7c478bd9Sstevel@tonic-gate } C[] = { 199*7c478bd9Sstevel@tonic-gate #ifdef _LITTLE_ENDIAN 200*7c478bd9Sstevel@tonic-gate { 0x00000000, 0x43300000 }, 201*7c478bd9Sstevel@tonic-gate { 0x00000000, 0x3ca00000 }, 202*7c478bd9Sstevel@tonic-gate { 0x00000000, 0x3fe00000 }, 203*7c478bd9Sstevel@tonic-gate { 0xffffffff, 0x3fdfffff }, 204*7c478bd9Sstevel@tonic-gate #else 205*7c478bd9Sstevel@tonic-gate { 0x43300000, 0x00000000 }, 206*7c478bd9Sstevel@tonic-gate { 0x3ca00000, 0x00000000 }, 207*7c478bd9Sstevel@tonic-gate { 0x3fe00000, 0x00000000 }, 208*7c478bd9Sstevel@tonic-gate { 0x3fdfffff, 0xffffffff }, /* nextafter(1/2, 0) */ 209*7c478bd9Sstevel@tonic-gate #endif 210*7c478bd9Sstevel@tonic-gate }; 211*7c478bd9Sstevel@tonic-gate 212*7c478bd9Sstevel@tonic-gate #define two52 C[0].d 213*7c478bd9Sstevel@tonic-gate #define twom53 C[1].d 214*7c478bd9Sstevel@tonic-gate #define half C[2].d 215*7c478bd9Sstevel@tonic-gate #define halfdec C[3].d 216*7c478bd9Sstevel@tonic-gate 217*7c478bd9Sstevel@tonic-gate static double 218*7c478bd9Sstevel@tonic-gate __arint_set_n(double *x, int nrx, int *pe) 219*7c478bd9Sstevel@tonic-gate { 220*7c478bd9Sstevel@tonic-gate int hx; 221*7c478bd9Sstevel@tonic-gate double rx, rmx; 222*7c478bd9Sstevel@tonic-gate 223*7c478bd9Sstevel@tonic-gate #ifdef _LITTLE_ENDIAN 224*7c478bd9Sstevel@tonic-gate hx = *(1+(int *)x); 225*7c478bd9Sstevel@tonic-gate #else 226*7c478bd9Sstevel@tonic-gate hx = *(int *)x; 227*7c478bd9Sstevel@tonic-gate #endif 228*7c478bd9Sstevel@tonic-gate if (hx >= 0x43300000) { 229*7c478bd9Sstevel@tonic-gate /* x >= 2^52, so it's already integral */ 230*7c478bd9Sstevel@tonic-gate if (nrx == 0) 231*7c478bd9Sstevel@tonic-gate *pe = 0; 232*7c478bd9Sstevel@tonic-gate else if (nrx == 1 && hx < 0x43400000) 233*7c478bd9Sstevel@tonic-gate *pe = 1; 234*7c478bd9Sstevel@tonic-gate else 235*7c478bd9Sstevel@tonic-gate *pe = 2; 236*7c478bd9Sstevel@tonic-gate return (*x); 237*7c478bd9Sstevel@tonic-gate } else if (hx < 0x3fe00000) { 238*7c478bd9Sstevel@tonic-gate /* x < 1/2 */ 239*7c478bd9Sstevel@tonic-gate if (nrx > 1 && hx == 0x3fdfffff) 240*7c478bd9Sstevel@tonic-gate *pe = (*x == halfdec)? 2 : 1; 241*7c478bd9Sstevel@tonic-gate else 242*7c478bd9Sstevel@tonic-gate *pe = 1; 243*7c478bd9Sstevel@tonic-gate return (0.0); 244*7c478bd9Sstevel@tonic-gate } 245*7c478bd9Sstevel@tonic-gate 246*7c478bd9Sstevel@tonic-gate rx = (*x + two52) - two52; 247*7c478bd9Sstevel@tonic-gate if (nrx == 0) { 248*7c478bd9Sstevel@tonic-gate *pe = (rx == *x)? 0 : 1; 249*7c478bd9Sstevel@tonic-gate } else { 250*7c478bd9Sstevel@tonic-gate rmx = rx - *x; 251*7c478bd9Sstevel@tonic-gate if (rmx < 0.0) 252*7c478bd9Sstevel@tonic-gate rmx = -rmx; 253*7c478bd9Sstevel@tonic-gate *pe = (nrx * twom53 * *x < half - rmx)? 1 : 2; 254*7c478bd9Sstevel@tonic-gate } 255*7c478bd9Sstevel@tonic-gate return (rx); 256*7c478bd9Sstevel@tonic-gate } 257*7c478bd9Sstevel@tonic-gate 258*7c478bd9Sstevel@tonic-gate /* 259*7c478bd9Sstevel@tonic-gate * Attempt to convert dd to a decimal record *pd according to the 260*7c478bd9Sstevel@tonic-gate * modes in *pm using double precision floating point. Return zero 261*7c478bd9Sstevel@tonic-gate * and sets *ps to reflect any exceptions incurred if successful. 262*7c478bd9Sstevel@tonic-gate * Return a nonzero value if unsuccessful. 263*7c478bd9Sstevel@tonic-gate */ 264*7c478bd9Sstevel@tonic-gate int 265*7c478bd9Sstevel@tonic-gate __fast_double_to_decimal(double *dd, decimal_mode *pm, decimal_record *pd, 266*7c478bd9Sstevel@tonic-gate fp_exception_field_type *ps) 267*7c478bd9Sstevel@tonic-gate { 268*7c478bd9Sstevel@tonic-gate int i, is, esum, eround, hd; 269*7c478bd9Sstevel@tonic-gate double dds; 270*7c478bd9Sstevel@tonic-gate __ieee_flags_type fb; 271*7c478bd9Sstevel@tonic-gate 272*7c478bd9Sstevel@tonic-gate if (pm->rd != fp_nearest) 273*7c478bd9Sstevel@tonic-gate return (1); 274*7c478bd9Sstevel@tonic-gate 275*7c478bd9Sstevel@tonic-gate if (pm->df == fixed_form) { 276*7c478bd9Sstevel@tonic-gate /* F format */ 277*7c478bd9Sstevel@tonic-gate if (pm->ndigits < 0 || pm->ndigits > __TBL_TENS_MAX) 278*7c478bd9Sstevel@tonic-gate return (1); 279*7c478bd9Sstevel@tonic-gate __get_ieee_flags(&fb); 280*7c478bd9Sstevel@tonic-gate dds = __dabs(dd); 281*7c478bd9Sstevel@tonic-gate esum = 0; 282*7c478bd9Sstevel@tonic-gate if (pm->ndigits) { 283*7c478bd9Sstevel@tonic-gate /* scale by a positive power of ten */ 284*7c478bd9Sstevel@tonic-gate if (pm->ndigits > __TBL_TENS_EXACT) { 285*7c478bd9Sstevel@tonic-gate dds *= __tbl_tens[pm->ndigits]; 286*7c478bd9Sstevel@tonic-gate esum = 2; 287*7c478bd9Sstevel@tonic-gate } else { 288*7c478bd9Sstevel@tonic-gate dds = __mul_set(dds, __tbl_tens[pm->ndigits], 289*7c478bd9Sstevel@tonic-gate &eround); 290*7c478bd9Sstevel@tonic-gate esum = eround; 291*7c478bd9Sstevel@tonic-gate } 292*7c478bd9Sstevel@tonic-gate } 293*7c478bd9Sstevel@tonic-gate if (dds > 2147483647999999744.0) { 294*7c478bd9Sstevel@tonic-gate __set_ieee_flags(&fb); 295*7c478bd9Sstevel@tonic-gate return (1); 296*7c478bd9Sstevel@tonic-gate } 297*7c478bd9Sstevel@tonic-gate dds = __arint_set_n(&dds, esum, &eround); 298*7c478bd9Sstevel@tonic-gate if (eround == 2) { 299*7c478bd9Sstevel@tonic-gate /* error is too large to round reliably; punt */ 300*7c478bd9Sstevel@tonic-gate __set_ieee_flags(&fb); 301*7c478bd9Sstevel@tonic-gate return (1); 302*7c478bd9Sstevel@tonic-gate } 303*7c478bd9Sstevel@tonic-gate if (dds == 0.0) { 304*7c478bd9Sstevel@tonic-gate is = (pm->ndigits > 0)? pm->ndigits : 1; 305*7c478bd9Sstevel@tonic-gate for (i = 0; i < is; i++) 306*7c478bd9Sstevel@tonic-gate pd->ds[i] = '0'; 307*7c478bd9Sstevel@tonic-gate pd->ds[is] = '\0'; 308*7c478bd9Sstevel@tonic-gate eround++; 309*7c478bd9Sstevel@tonic-gate } else { 310*7c478bd9Sstevel@tonic-gate is = __double_to_digits(dds, pd->ds, pm->ndigits); 311*7c478bd9Sstevel@tonic-gate } 312*7c478bd9Sstevel@tonic-gate pd->ndigits = is; 313*7c478bd9Sstevel@tonic-gate pd->exponent = -pm->ndigits; 314*7c478bd9Sstevel@tonic-gate } else { 315*7c478bd9Sstevel@tonic-gate /* E format */ 316*7c478bd9Sstevel@tonic-gate if (pm->ndigits < 1 || pm->ndigits > 18) 317*7c478bd9Sstevel@tonic-gate return (1); 318*7c478bd9Sstevel@tonic-gate __get_ieee_flags(&fb); 319*7c478bd9Sstevel@tonic-gate dds = __dabs(dd); 320*7c478bd9Sstevel@tonic-gate /* find the decade containing dds */ 321*7c478bd9Sstevel@tonic-gate #ifdef _LITTLE_ENDIAN 322*7c478bd9Sstevel@tonic-gate hd = *(1+(int *)dd); 323*7c478bd9Sstevel@tonic-gate #else 324*7c478bd9Sstevel@tonic-gate hd = *(int *)dd; 325*7c478bd9Sstevel@tonic-gate #endif 326*7c478bd9Sstevel@tonic-gate hd = (hd >> 20) & 0x7ff; 327*7c478bd9Sstevel@tonic-gate if (hd >= 0x400) { 328*7c478bd9Sstevel@tonic-gate if (hd > 0x4e0) 329*7c478bd9Sstevel@tonic-gate i = TBL_DECADE_MAX; 330*7c478bd9Sstevel@tonic-gate else 331*7c478bd9Sstevel@tonic-gate i = TBL_DECADE_MAX - ((0x4e0 - hd) >> 2); 332*7c478bd9Sstevel@tonic-gate } else { 333*7c478bd9Sstevel@tonic-gate if (hd < 0x358) 334*7c478bd9Sstevel@tonic-gate i = 0; 335*7c478bd9Sstevel@tonic-gate else 336*7c478bd9Sstevel@tonic-gate i = TBL_DECADE_OFFSET - ((0x3ff - hd) >> 2); 337*7c478bd9Sstevel@tonic-gate } 338*7c478bd9Sstevel@tonic-gate while (dds < tbl_decade[i]) 339*7c478bd9Sstevel@tonic-gate i--; 340*7c478bd9Sstevel@tonic-gate /* determine the power of ten by which to scale */ 341*7c478bd9Sstevel@tonic-gate i = pm->ndigits - 1 - (i - TBL_DECADE_OFFSET); 342*7c478bd9Sstevel@tonic-gate esum = 0; 343*7c478bd9Sstevel@tonic-gate if (i > 0) { 344*7c478bd9Sstevel@tonic-gate /* scale by a positive power of ten */ 345*7c478bd9Sstevel@tonic-gate if (i > __TBL_TENS_EXACT) { 346*7c478bd9Sstevel@tonic-gate if (i > __TBL_TENS_MAX) { 347*7c478bd9Sstevel@tonic-gate __set_ieee_flags(&fb); 348*7c478bd9Sstevel@tonic-gate return (1); 349*7c478bd9Sstevel@tonic-gate } 350*7c478bd9Sstevel@tonic-gate dds *= __tbl_tens[i]; 351*7c478bd9Sstevel@tonic-gate esum = 2; 352*7c478bd9Sstevel@tonic-gate } else { 353*7c478bd9Sstevel@tonic-gate dds = __mul_set(dds, __tbl_tens[i], &eround); 354*7c478bd9Sstevel@tonic-gate esum = eround; 355*7c478bd9Sstevel@tonic-gate } 356*7c478bd9Sstevel@tonic-gate } else if (i < 0) { 357*7c478bd9Sstevel@tonic-gate /* scale by a negative power of ten */ 358*7c478bd9Sstevel@tonic-gate if (-i > __TBL_TENS_EXACT) { 359*7c478bd9Sstevel@tonic-gate if (-i > __TBL_TENS_MAX) { 360*7c478bd9Sstevel@tonic-gate __set_ieee_flags(&fb); 361*7c478bd9Sstevel@tonic-gate return (1); 362*7c478bd9Sstevel@tonic-gate } 363*7c478bd9Sstevel@tonic-gate dds /= __tbl_tens[-i]; 364*7c478bd9Sstevel@tonic-gate esum = 2; 365*7c478bd9Sstevel@tonic-gate } else { 366*7c478bd9Sstevel@tonic-gate dds = __div_set(dds, __tbl_tens[-i], &eround); 367*7c478bd9Sstevel@tonic-gate esum = eround; 368*7c478bd9Sstevel@tonic-gate } 369*7c478bd9Sstevel@tonic-gate } 370*7c478bd9Sstevel@tonic-gate dds = __arint_set_n(&dds, esum, &eround); 371*7c478bd9Sstevel@tonic-gate if (eround == 2) { 372*7c478bd9Sstevel@tonic-gate /* error is too large to round reliably; punt */ 373*7c478bd9Sstevel@tonic-gate __set_ieee_flags(&fb); 374*7c478bd9Sstevel@tonic-gate return (1); 375*7c478bd9Sstevel@tonic-gate } 376*7c478bd9Sstevel@tonic-gate is = __double_to_digits(dds, pd->ds, 1); 377*7c478bd9Sstevel@tonic-gate if (is > pm->ndigits) { 378*7c478bd9Sstevel@tonic-gate /* 379*7c478bd9Sstevel@tonic-gate * The result rounded up to the next larger power 380*7c478bd9Sstevel@tonic-gate * of ten; just discard the last zero and adjust 381*7c478bd9Sstevel@tonic-gate * the exponent. 382*7c478bd9Sstevel@tonic-gate */ 383*7c478bd9Sstevel@tonic-gate pd->ds[--is] = '\0'; 384*7c478bd9Sstevel@tonic-gate i--; 385*7c478bd9Sstevel@tonic-gate } 386*7c478bd9Sstevel@tonic-gate pd->ndigits = is; 387*7c478bd9Sstevel@tonic-gate pd->exponent = -i; 388*7c478bd9Sstevel@tonic-gate } 389*7c478bd9Sstevel@tonic-gate *ps = (eround == 0)? 0 : (1 << fp_inexact); 390*7c478bd9Sstevel@tonic-gate __set_ieee_flags(&fb); 391*7c478bd9Sstevel@tonic-gate return (0); 392*7c478bd9Sstevel@tonic-gate } 393