1 1.11 christos /* $NetBSD: gdtoa.c,v 1.11 2024/01/20 14:52:47 christos Exp $ */ 2 1.1 kleink 3 1.1 kleink /**************************************************************** 4 1.1 kleink 5 1.1 kleink The author of this software is David M. Gay. 6 1.1 kleink 7 1.1 kleink Copyright (C) 1998, 1999 by Lucent Technologies 8 1.1 kleink All Rights Reserved 9 1.1 kleink 10 1.1 kleink Permission to use, copy, modify, and distribute this software and 11 1.1 kleink its documentation for any purpose and without fee is hereby 12 1.1 kleink granted, provided that the above copyright notice appear in all 13 1.1 kleink copies and that both that the copyright notice and this 14 1.1 kleink permission notice and warranty disclaimer appear in supporting 15 1.1 kleink documentation, and that the name of Lucent or any of its entities 16 1.1 kleink not be used in advertising or publicity pertaining to 17 1.1 kleink distribution of the software without specific, written prior 18 1.1 kleink permission. 19 1.1 kleink 20 1.1 kleink LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 21 1.1 kleink INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 22 1.1 kleink IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY 23 1.1 kleink SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 24 1.1 kleink WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 25 1.1 kleink IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 26 1.1 kleink ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF 27 1.1 kleink THIS SOFTWARE. 28 1.1 kleink 29 1.1 kleink ****************************************************************/ 30 1.1 kleink 31 1.1 kleink /* Please send bug reports to David M. Gay (dmg at acm dot org, 32 1.1 kleink * with " at " changed at "@" and " dot " changed to "."). */ 33 1.1 kleink 34 1.1 kleink #include "gdtoaimp.h" 35 1.1 kleink 36 1.1 kleink static Bigint * 37 1.1 kleink #ifdef KR_headers 38 1.1 kleink bitstob(bits, nbits, bbits) ULong *bits; int nbits; int *bbits; 39 1.1 kleink #else 40 1.1 kleink bitstob(ULong *bits, int nbits, int *bbits) 41 1.1 kleink #endif 42 1.1 kleink { 43 1.1 kleink int i, k; 44 1.1 kleink Bigint *b; 45 1.1 kleink ULong *be, *x, *x0; 46 1.1 kleink 47 1.1 kleink i = ULbits; 48 1.1 kleink k = 0; 49 1.1 kleink while(i < nbits) { 50 1.1 kleink i <<= 1; 51 1.1 kleink k++; 52 1.1 kleink } 53 1.1 kleink #ifndef Pack_32 54 1.1 kleink if (!k) 55 1.1 kleink k = 1; 56 1.1 kleink #endif 57 1.1 kleink b = Balloc(k); 58 1.4 christos if (b == NULL) 59 1.4 christos return NULL; 60 1.2 christos be = bits + (((unsigned int)nbits - 1) >> kshift); 61 1.1 kleink x = x0 = b->x; 62 1.1 kleink do { 63 1.1 kleink *x++ = *bits & ALL_ON; 64 1.1 kleink #ifdef Pack_16 65 1.1 kleink *x++ = (*bits >> 16) & ALL_ON; 66 1.1 kleink #endif 67 1.1 kleink } while(++bits <= be); 68 1.6 christos ptrdiff_t td = x - x0; 69 1.6 christos _DIAGASSERT(__type_fit(int, td)); 70 1.6 christos i = (int)td; 71 1.1 kleink while(!x0[--i]) 72 1.1 kleink if (!i) { 73 1.1 kleink b->wds = 0; 74 1.1 kleink *bbits = 0; 75 1.1 kleink goto ret; 76 1.1 kleink } 77 1.1 kleink b->wds = i + 1; 78 1.1 kleink *bbits = i*ULbits + 32 - hi0bits(b->x[i]); 79 1.1 kleink ret: 80 1.1 kleink return b; 81 1.1 kleink } 82 1.1 kleink 83 1.1 kleink /* dtoa for IEEE arithmetic (dmg): convert double to ASCII string. 84 1.1 kleink * 85 1.1 kleink * Inspired by "How to Print Floating-Point Numbers Accurately" by 86 1.1 kleink * Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 112-126]. 87 1.1 kleink * 88 1.1 kleink * Modifications: 89 1.1 kleink * 1. Rather than iterating, we use a simple numeric overestimate 90 1.1 kleink * to determine k = floor(log10(d)). We scale relevant 91 1.1 kleink * quantities using O(log2(k)) rather than O(k) multiplications. 92 1.1 kleink * 2. For some modes > 2 (corresponding to ecvt and fcvt), we don't 93 1.1 kleink * try to generate digits strictly left to right. Instead, we 94 1.1 kleink * compute with fewer bits and propagate the carry if necessary 95 1.1 kleink * when rounding the final digit up. This is often faster. 96 1.1 kleink * 3. Under the assumption that input will be rounded nearest, 97 1.1 kleink * mode 0 renders 1e23 as 1e23 rather than 9.999999999999999e22. 98 1.1 kleink * That is, we allow equality in stopping tests when the 99 1.1 kleink * round-nearest rule will give the same floating-point value 100 1.1 kleink * as would satisfaction of the stopping test with strict 101 1.1 kleink * inequality. 102 1.1 kleink * 4. We remove common factors of powers of 2 from relevant 103 1.1 kleink * quantities. 104 1.1 kleink * 5. When converting floating-point integers less than 1e16, 105 1.1 kleink * we use floating-point arithmetic rather than resorting 106 1.1 kleink * to multiple-precision integers. 107 1.1 kleink * 6. When asked to produce fewer than 15 digits, we first try 108 1.1 kleink * to get by with floating-point arithmetic; we resort to 109 1.1 kleink * multiple-precision integer arithmetic only if we cannot 110 1.1 kleink * guarantee that the floating-point calculation has given 111 1.1 kleink * the correctly rounded result. For k requested digits and 112 1.1 kleink * "uniformly" distributed input, the probability is 113 1.1 kleink * something like 10^(k-15) that we must resort to the Long 114 1.1 kleink * calculation. 115 1.1 kleink */ 116 1.1 kleink 117 1.1 kleink char * 118 1.1 kleink gdtoa 119 1.1 kleink #ifdef KR_headers 120 1.1 kleink (fpi, be, bits, kindp, mode, ndigits, decpt, rve) 121 1.7 riastrad CONST FPI *fpi; int be; ULong *bits; 122 1.1 kleink int *kindp, mode, ndigits, *decpt; char **rve; 123 1.1 kleink #else 124 1.7 riastrad (CONST FPI *fpi, int be, ULong *bits, int *kindp, int mode, int ndigits, int *decpt, char **rve) 125 1.1 kleink #endif 126 1.1 kleink { 127 1.1 kleink /* Arguments ndigits and decpt are similar to the second and third 128 1.1 kleink arguments of ecvt and fcvt; trailing zeros are suppressed from 129 1.1 kleink the returned string. If not null, *rve is set to point 130 1.1 kleink to the end of the return value. If d is +-Infinity or NaN, 131 1.9 dholland then *decpt is set to -32768. 132 1.5 christos be = exponent: value = (integer represented by bits) * (2 to the power of be). 133 1.1 kleink 134 1.1 kleink mode: 135 1.1 kleink 0 ==> shortest string that yields d when read in 136 1.1 kleink and rounded to nearest. 137 1.1 kleink 1 ==> like 0, but with Steele & White stopping rule; 138 1.1 kleink e.g. with IEEE P754 arithmetic , mode 0 gives 139 1.1 kleink 1e23 whereas mode 1 gives 9.999999999999999e22. 140 1.1 kleink 2 ==> max(1,ndigits) significant digits. This gives a 141 1.1 kleink return value similar to that of ecvt, except 142 1.1 kleink that trailing zeros are suppressed. 143 1.1 kleink 3 ==> through ndigits past the decimal point. This 144 1.1 kleink gives a return value similar to that from fcvt, 145 1.1 kleink except that trailing zeros are suppressed, and 146 1.1 kleink ndigits can be negative. 147 1.1 kleink 4-9 should give the same return values as 2-3, i.e., 148 1.1 kleink 4 <= mode <= 9 ==> same return as mode 149 1.1 kleink 2 + (mode & 1). These modes are mainly for 150 1.1 kleink debugging; often they run slower but sometimes 151 1.1 kleink faster than modes 2-3. 152 1.1 kleink 4,5,8,9 ==> left-to-right digit generation. 153 1.1 kleink 6-9 ==> don't try fast floating-point estimate 154 1.1 kleink (if applicable). 155 1.1 kleink 156 1.1 kleink Values of mode other than 0-9 are treated as mode 0. 157 1.1 kleink 158 1.1 kleink Sufficient space is allocated to the return value 159 1.1 kleink to hold the suppressed trailing zeros. 160 1.1 kleink */ 161 1.1 kleink 162 1.2 christos int bbits, b2, b5, be0, dig, i, ieps, ilim = 0, ilim0, ilim1 = 0, inex; 163 1.2 christos int j, jj1, k, k0, k_check, kind, leftright, m2, m5, nbits; 164 1.1 kleink int rdir, s2, s5, spec_case, try_quick; 165 1.1 kleink Long L; 166 1.1 kleink Bigint *b, *b1, *delta, *mlo, *mhi, *mhi1, *S; 167 1.5 christos double d2, ds; 168 1.1 kleink char *s, *s0; 169 1.5 christos U d, eps; 170 1.1 kleink 171 1.1 kleink #ifndef MULTIPLE_THREADS 172 1.1 kleink if (dtoa_result) { 173 1.1 kleink freedtoa(dtoa_result); 174 1.1 kleink dtoa_result = 0; 175 1.1 kleink } 176 1.1 kleink #endif 177 1.1 kleink inex = 0; 178 1.4 christos if (*kindp & STRTOG_NoMemory) 179 1.4 christos return NULL; 180 1.1 kleink kind = *kindp &= ~STRTOG_Inexact; 181 1.1 kleink switch(kind & STRTOG_Retmask) { 182 1.1 kleink case STRTOG_Zero: 183 1.1 kleink goto ret_zero; 184 1.1 kleink case STRTOG_Normal: 185 1.1 kleink case STRTOG_Denormal: 186 1.1 kleink break; 187 1.1 kleink case STRTOG_Infinite: 188 1.1 kleink *decpt = -32768; 189 1.1 kleink return nrv_alloc("Infinity", rve, 8); 190 1.1 kleink case STRTOG_NaN: 191 1.1 kleink *decpt = -32768; 192 1.1 kleink return nrv_alloc("NaN", rve, 3); 193 1.1 kleink default: 194 1.1 kleink return 0; 195 1.1 kleink } 196 1.1 kleink b = bitstob(bits, nbits = fpi->nbits, &bbits); 197 1.4 christos if (b == NULL) 198 1.4 christos return NULL; 199 1.1 kleink be0 = be; 200 1.1 kleink if ( (i = trailz(b)) !=0) { 201 1.1 kleink rshift(b, i); 202 1.1 kleink be += i; 203 1.1 kleink bbits -= i; 204 1.1 kleink } 205 1.1 kleink if (!b->wds) { 206 1.1 kleink Bfree(b); 207 1.1 kleink ret_zero: 208 1.1 kleink *decpt = 1; 209 1.1 kleink return nrv_alloc("0", rve, 1); 210 1.1 kleink } 211 1.1 kleink 212 1.5 christos dval(&d) = b2d(b, &i); 213 1.1 kleink i = be + bbits - 1; 214 1.5 christos word0(&d) &= Frac_mask1; 215 1.5 christos word0(&d) |= Exp_11; 216 1.1 kleink #ifdef IBM 217 1.5 christos if ( (j = 11 - hi0bits(word0(&d) & Frac_mask)) !=0) 218 1.5 christos dval(&d) /= 1 << j; 219 1.1 kleink #endif 220 1.1 kleink 221 1.1 kleink /* log(x) ~=~ log(1.5) + (x-1.5)/1.5 222 1.1 kleink * log10(x) = log(x) / log(10) 223 1.1 kleink * ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10)) 224 1.5 christos * log10(&d) = (i-Bias)*log(2)/log(10) + log10(d2) 225 1.1 kleink * 226 1.5 christos * This suggests computing an approximation k to log10(&d) by 227 1.1 kleink * 228 1.1 kleink * k = (i - Bias)*0.301029995663981 229 1.1 kleink * + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 ); 230 1.1 kleink * 231 1.1 kleink * We want k to be too large rather than too small. 232 1.1 kleink * The error in the first-order Taylor series approximation 233 1.1 kleink * is in our favor, so we just round up the constant enough 234 1.1 kleink * to compensate for any error in the multiplication of 235 1.1 kleink * (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077, 236 1.1 kleink * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14, 237 1.1 kleink * adding 1e-13 to the constant term more than suffices. 238 1.1 kleink * Hence we adjust the constant term to 0.1760912590558. 239 1.1 kleink * (We could get a more accurate k by invoking log10, 240 1.1 kleink * but this is probably not worthwhile.) 241 1.1 kleink */ 242 1.1 kleink #ifdef IBM 243 1.1 kleink i <<= 2; 244 1.1 kleink i += j; 245 1.1 kleink #endif 246 1.5 christos ds = (dval(&d)-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981; 247 1.1 kleink 248 1.1 kleink /* correct assumption about exponent range */ 249 1.1 kleink if ((j = i) < 0) 250 1.1 kleink j = -j; 251 1.1 kleink if ((j -= 1077) > 0) 252 1.1 kleink ds += j * 7e-17; 253 1.1 kleink 254 1.1 kleink k = (int)ds; 255 1.1 kleink if (ds < 0. && ds != k) 256 1.1 kleink k--; /* want k = floor(ds) */ 257 1.1 kleink k_check = 1; 258 1.1 kleink #ifdef IBM 259 1.1 kleink j = be + bbits - 1; 260 1.2 christos if ( (jj1 = j & 3) !=0) 261 1.5 christos dval(&d) *= 1 << jj1; 262 1.5 christos word0(&d) += j << Exp_shift - 2 & Exp_mask; 263 1.1 kleink #else 264 1.5 christos word0(&d) += (be + bbits - 1) << Exp_shift; 265 1.1 kleink #endif 266 1.1 kleink if (k >= 0 && k <= Ten_pmax) { 267 1.5 christos if (dval(&d) < tens[k]) 268 1.1 kleink k--; 269 1.1 kleink k_check = 0; 270 1.1 kleink } 271 1.1 kleink j = bbits - i - 1; 272 1.1 kleink if (j >= 0) { 273 1.1 kleink b2 = 0; 274 1.1 kleink s2 = j; 275 1.1 kleink } 276 1.1 kleink else { 277 1.1 kleink b2 = -j; 278 1.1 kleink s2 = 0; 279 1.1 kleink } 280 1.1 kleink if (k >= 0) { 281 1.1 kleink b5 = 0; 282 1.1 kleink s5 = k; 283 1.1 kleink s2 += k; 284 1.1 kleink } 285 1.1 kleink else { 286 1.1 kleink b2 -= k; 287 1.1 kleink b5 = -k; 288 1.1 kleink s5 = 0; 289 1.1 kleink } 290 1.1 kleink if (mode < 0 || mode > 9) 291 1.1 kleink mode = 0; 292 1.1 kleink try_quick = 1; 293 1.1 kleink if (mode > 5) { 294 1.1 kleink mode -= 4; 295 1.1 kleink try_quick = 0; 296 1.1 kleink } 297 1.5 christos else if (i >= -4 - Emin || i < Emin) 298 1.5 christos try_quick = 0; 299 1.1 kleink leftright = 1; 300 1.5 christos ilim = ilim1 = -1; /* Values for cases 0 and 1; done here to */ 301 1.5 christos /* silence erroneous "gcc -Wall" warning. */ 302 1.1 kleink switch(mode) { 303 1.1 kleink case 0: 304 1.1 kleink case 1: 305 1.1 kleink i = (int)(nbits * .30103) + 3; 306 1.1 kleink ndigits = 0; 307 1.1 kleink break; 308 1.1 kleink case 2: 309 1.1 kleink leftright = 0; 310 1.2 christos /*FALLTHROUGH*/ 311 1.1 kleink case 4: 312 1.1 kleink if (ndigits <= 0) 313 1.1 kleink ndigits = 1; 314 1.1 kleink ilim = ilim1 = i = ndigits; 315 1.1 kleink break; 316 1.1 kleink case 3: 317 1.1 kleink leftright = 0; 318 1.2 christos /*FALLTHROUGH*/ 319 1.1 kleink case 5: 320 1.1 kleink i = ndigits + k + 1; 321 1.1 kleink ilim = i; 322 1.1 kleink ilim1 = i - 1; 323 1.1 kleink if (i <= 0) 324 1.1 kleink i = 1; 325 1.1 kleink } 326 1.3 christos s = s0 = rv_alloc((size_t)i); 327 1.4 christos if (s == NULL) 328 1.4 christos return NULL; 329 1.1 kleink 330 1.1 kleink if ( (rdir = fpi->rounding - 1) !=0) { 331 1.1 kleink if (rdir < 0) 332 1.1 kleink rdir = 2; 333 1.1 kleink if (kind & STRTOG_Neg) 334 1.1 kleink rdir = 3 - rdir; 335 1.1 kleink } 336 1.1 kleink 337 1.1 kleink /* Now rdir = 0 ==> round near, 1 ==> round up, 2 ==> round down. */ 338 1.1 kleink 339 1.1 kleink if (ilim >= 0 && ilim <= Quick_max && try_quick && !rdir 340 1.1 kleink #ifndef IMPRECISE_INEXACT 341 1.1 kleink && k == 0 342 1.1 kleink #endif 343 1.1 kleink ) { 344 1.1 kleink 345 1.1 kleink /* Try to get by with floating-point arithmetic. */ 346 1.1 kleink 347 1.1 kleink i = 0; 348 1.5 christos d2 = dval(&d); 349 1.1 kleink #ifdef IBM 350 1.5 christos if ( (j = 11 - hi0bits(word0(&d) & Frac_mask)) !=0) 351 1.5 christos dval(&d) /= 1 << j; 352 1.1 kleink #endif 353 1.1 kleink k0 = k; 354 1.1 kleink ilim0 = ilim; 355 1.1 kleink ieps = 2; /* conservative */ 356 1.1 kleink if (k > 0) { 357 1.1 kleink ds = tens[k&0xf]; 358 1.2 christos j = (unsigned int)k >> 4; 359 1.1 kleink if (j & Bletch) { 360 1.1 kleink /* prevent overflows */ 361 1.1 kleink j &= Bletch - 1; 362 1.5 christos dval(&d) /= bigtens[n_bigtens-1]; 363 1.1 kleink ieps++; 364 1.1 kleink } 365 1.2 christos for(; j; j /= 2, i++) 366 1.1 kleink if (j & 1) { 367 1.1 kleink ieps++; 368 1.1 kleink ds *= bigtens[i]; 369 1.1 kleink } 370 1.1 kleink } 371 1.1 kleink else { 372 1.1 kleink ds = 1.; 373 1.2 christos if ( (jj1 = -k) !=0) { 374 1.5 christos dval(&d) *= tens[jj1 & 0xf]; 375 1.11 christos for(j = (unsigned int)jj1 >> 4; j; j = (unsigned int)j >> 1, i++) 376 1.1 kleink if (j & 1) { 377 1.1 kleink ieps++; 378 1.5 christos dval(&d) *= bigtens[i]; 379 1.1 kleink } 380 1.1 kleink } 381 1.1 kleink } 382 1.5 christos if (k_check && dval(&d) < 1. && ilim > 0) { 383 1.1 kleink if (ilim1 <= 0) 384 1.1 kleink goto fast_failed; 385 1.1 kleink ilim = ilim1; 386 1.1 kleink k--; 387 1.5 christos dval(&d) *= 10.; 388 1.1 kleink ieps++; 389 1.1 kleink } 390 1.5 christos dval(&eps) = ieps*dval(&d) + 7.; 391 1.5 christos word0(&eps) -= (P-1)*Exp_msk1; 392 1.1 kleink if (ilim == 0) { 393 1.1 kleink S = mhi = 0; 394 1.5 christos dval(&d) -= 5.; 395 1.5 christos if (dval(&d) > dval(&eps)) 396 1.1 kleink goto one_digit; 397 1.5 christos if (dval(&d) < -dval(&eps)) 398 1.1 kleink goto no_digits; 399 1.1 kleink goto fast_failed; 400 1.1 kleink } 401 1.1 kleink #ifndef No_leftright 402 1.1 kleink if (leftright) { 403 1.1 kleink /* Use Steele & White method of only 404 1.1 kleink * generating digits needed. 405 1.1 kleink */ 406 1.5 christos dval(&eps) = ds*0.5/tens[ilim-1] - dval(&eps); 407 1.1 kleink for(i = 0;;) { 408 1.5 christos L = (Long)(dval(&d)/ds); 409 1.5 christos dval(&d) -= L*ds; 410 1.1 kleink *s++ = '0' + (int)L; 411 1.5 christos if (dval(&d) < dval(&eps)) { 412 1.5 christos if (dval(&d)) 413 1.1 kleink inex = STRTOG_Inexlo; 414 1.1 kleink goto ret1; 415 1.1 kleink } 416 1.5 christos if (ds - dval(&d) < dval(&eps)) 417 1.1 kleink goto bump_up; 418 1.1 kleink if (++i >= ilim) 419 1.1 kleink break; 420 1.5 christos dval(&eps) *= 10.; 421 1.5 christos dval(&d) *= 10.; 422 1.1 kleink } 423 1.1 kleink } 424 1.1 kleink else { 425 1.1 kleink #endif 426 1.1 kleink /* Generate ilim digits, then fix them up. */ 427 1.5 christos dval(&eps) *= tens[ilim-1]; 428 1.5 christos for(i = 1;; i++, dval(&d) *= 10.) { 429 1.5 christos if ( (L = (Long)(dval(&d)/ds)) !=0) 430 1.5 christos dval(&d) -= L*ds; 431 1.1 kleink *s++ = '0' + (int)L; 432 1.1 kleink if (i == ilim) { 433 1.1 kleink ds *= 0.5; 434 1.5 christos if (dval(&d) > ds + dval(&eps)) 435 1.1 kleink goto bump_up; 436 1.5 christos else if (dval(&d) < ds - dval(&eps)) { 437 1.5 christos if (dval(&d)) 438 1.1 kleink inex = STRTOG_Inexlo; 439 1.5 christos goto clear_trailing0; 440 1.1 kleink } 441 1.1 kleink break; 442 1.1 kleink } 443 1.1 kleink } 444 1.1 kleink #ifndef No_leftright 445 1.1 kleink } 446 1.1 kleink #endif 447 1.1 kleink fast_failed: 448 1.1 kleink s = s0; 449 1.5 christos dval(&d) = d2; 450 1.1 kleink k = k0; 451 1.1 kleink ilim = ilim0; 452 1.1 kleink } 453 1.1 kleink 454 1.1 kleink /* Do we have a "small" integer? */ 455 1.1 kleink 456 1.1 kleink if (be >= 0 && k <= Int_max) { 457 1.1 kleink /* Yes. */ 458 1.1 kleink ds = tens[k]; 459 1.1 kleink if (ndigits < 0 && ilim <= 0) { 460 1.1 kleink S = mhi = 0; 461 1.5 christos if (ilim < 0 || dval(&d) <= 5*ds) 462 1.1 kleink goto no_digits; 463 1.1 kleink goto one_digit; 464 1.1 kleink } 465 1.5 christos for(i = 1;; i++, dval(&d) *= 10.) { 466 1.5 christos L = dval(&d) / ds; 467 1.5 christos dval(&d) -= L*ds; 468 1.1 kleink #ifdef Check_FLT_ROUNDS 469 1.1 kleink /* If FLT_ROUNDS == 2, L will usually be high by 1 */ 470 1.5 christos if (dval(&d) < 0) { 471 1.1 kleink L--; 472 1.5 christos dval(&d) += ds; 473 1.1 kleink } 474 1.1 kleink #endif 475 1.1 kleink *s++ = '0' + (int)L; 476 1.5 christos if (dval(&d) == 0.) 477 1.1 kleink break; 478 1.1 kleink if (i == ilim) { 479 1.1 kleink if (rdir) { 480 1.1 kleink if (rdir == 1) 481 1.1 kleink goto bump_up; 482 1.1 kleink inex = STRTOG_Inexlo; 483 1.1 kleink goto ret1; 484 1.1 kleink } 485 1.5 christos dval(&d) += dval(&d); 486 1.5 christos #ifdef ROUND_BIASED 487 1.5 christos if (dval(&d) >= ds) 488 1.5 christos #else 489 1.5 christos if (dval(&d) > ds || (dval(&d) == ds && L & 1)) 490 1.5 christos #endif 491 1.5 christos { 492 1.1 kleink bump_up: 493 1.1 kleink inex = STRTOG_Inexhi; 494 1.1 kleink while(*--s == '9') 495 1.1 kleink if (s == s0) { 496 1.1 kleink k++; 497 1.1 kleink *s = '0'; 498 1.1 kleink break; 499 1.1 kleink } 500 1.1 kleink ++*s++; 501 1.1 kleink } 502 1.5 christos else { 503 1.1 kleink inex = STRTOG_Inexlo; 504 1.5 christos clear_trailing0: 505 1.5 christos while(*--s == '0'){} 506 1.5 christos ++s; 507 1.5 christos } 508 1.1 kleink break; 509 1.1 kleink } 510 1.1 kleink } 511 1.1 kleink goto ret1; 512 1.1 kleink } 513 1.1 kleink 514 1.1 kleink m2 = b2; 515 1.1 kleink m5 = b5; 516 1.1 kleink mhi = mlo = 0; 517 1.1 kleink if (leftright) { 518 1.5 christos i = nbits - bbits; 519 1.5 christos if (be - i++ < fpi->emin && mode != 3 && mode != 5) { 520 1.5 christos /* denormal */ 521 1.5 christos i = be - fpi->emin + 1; 522 1.5 christos if (mode >= 2 && ilim > 0 && ilim < i) 523 1.5 christos goto small_ilim; 524 1.1 kleink } 525 1.5 christos else if (mode >= 2) { 526 1.5 christos small_ilim: 527 1.1 kleink j = ilim - 1; 528 1.1 kleink if (m5 >= j) 529 1.1 kleink m5 -= j; 530 1.1 kleink else { 531 1.1 kleink s5 += j -= m5; 532 1.1 kleink b5 += j; 533 1.1 kleink m5 = 0; 534 1.1 kleink } 535 1.1 kleink if ((i = ilim) < 0) { 536 1.1 kleink m2 -= i; 537 1.1 kleink i = 0; 538 1.1 kleink } 539 1.1 kleink } 540 1.1 kleink b2 += i; 541 1.1 kleink s2 += i; 542 1.1 kleink mhi = i2b(1); 543 1.1 kleink } 544 1.1 kleink if (m2 > 0 && s2 > 0) { 545 1.1 kleink i = m2 < s2 ? m2 : s2; 546 1.1 kleink b2 -= i; 547 1.1 kleink m2 -= i; 548 1.1 kleink s2 -= i; 549 1.1 kleink } 550 1.1 kleink if (b5 > 0) { 551 1.1 kleink if (leftright) { 552 1.1 kleink if (m5 > 0) { 553 1.1 kleink mhi = pow5mult(mhi, m5); 554 1.4 christos if (mhi == NULL) 555 1.4 christos return NULL; 556 1.1 kleink b1 = mult(mhi, b); 557 1.4 christos if (b1 == NULL) 558 1.4 christos return NULL; 559 1.1 kleink Bfree(b); 560 1.1 kleink b = b1; 561 1.1 kleink } 562 1.4 christos if ( (j = b5 - m5) !=0) { 563 1.1 kleink b = pow5mult(b, j); 564 1.4 christos if (b == NULL) 565 1.4 christos return NULL; 566 1.4 christos } 567 1.1 kleink } 568 1.4 christos else { 569 1.1 kleink b = pow5mult(b, b5); 570 1.4 christos if (b == NULL) 571 1.4 christos return NULL; 572 1.4 christos } 573 1.1 kleink } 574 1.1 kleink S = i2b(1); 575 1.4 christos if (S == NULL) 576 1.4 christos return NULL; 577 1.4 christos if (s5 > 0) { 578 1.1 kleink S = pow5mult(S, s5); 579 1.4 christos if (S == NULL) 580 1.4 christos return NULL; 581 1.4 christos } 582 1.1 kleink 583 1.1 kleink /* Check for special case that d is a normalized power of 2. */ 584 1.1 kleink 585 1.1 kleink spec_case = 0; 586 1.1 kleink if (mode < 2) { 587 1.1 kleink if (bbits == 1 && be0 > fpi->emin + 1) { 588 1.1 kleink /* The special case */ 589 1.1 kleink b2++; 590 1.1 kleink s2++; 591 1.1 kleink spec_case = 1; 592 1.1 kleink } 593 1.1 kleink } 594 1.1 kleink 595 1.1 kleink /* Arrange for convenient computation of quotients: 596 1.1 kleink * shift left if necessary so divisor has 4 leading 0 bits. 597 1.1 kleink * 598 1.1 kleink * Perhaps we should just compute leading 28 bits of S once 599 1.1 kleink * and for all and pass them and a shift to quorem, so it 600 1.1 kleink * can do shifts and ors to compute the numerator for q. 601 1.1 kleink */ 602 1.5 christos i = ((s5 ? hi0bits(S->x[S->wds-1]) : ULbits - 1) - s2 - 4) & kmask; 603 1.5 christos m2 += i; 604 1.8 christos if ((b2 += i) > 0) { 605 1.1 kleink b = lshift(b, b2); 606 1.8 christos if (b == NULL) 607 1.8 christos return NULL; 608 1.8 christos } 609 1.8 christos if ((s2 += i) > 0) { 610 1.1 kleink S = lshift(S, s2); 611 1.8 christos if (S == NULL) 612 1.8 christos return NULL; 613 1.8 christos } 614 1.1 kleink if (k_check) { 615 1.1 kleink if (cmp(b,S) < 0) { 616 1.1 kleink k--; 617 1.1 kleink b = multadd(b, 10, 0); /* we botched the k estimate */ 618 1.4 christos if (b == NULL) 619 1.4 christos return NULL; 620 1.4 christos if (leftright) { 621 1.1 kleink mhi = multadd(mhi, 10, 0); 622 1.4 christos if (mhi == NULL) 623 1.4 christos return NULL; 624 1.4 christos } 625 1.1 kleink ilim = ilim1; 626 1.1 kleink } 627 1.1 kleink } 628 1.1 kleink if (ilim <= 0 && mode > 2) { 629 1.1 kleink if (ilim < 0 || cmp(b,S = multadd(S,5,0)) <= 0) { 630 1.1 kleink /* no digits, fcvt style */ 631 1.1 kleink no_digits: 632 1.1 kleink k = -1 - ndigits; 633 1.1 kleink inex = STRTOG_Inexlo; 634 1.1 kleink goto ret; 635 1.1 kleink } 636 1.1 kleink one_digit: 637 1.1 kleink inex = STRTOG_Inexhi; 638 1.1 kleink *s++ = '1'; 639 1.1 kleink k++; 640 1.1 kleink goto ret; 641 1.1 kleink } 642 1.1 kleink if (leftright) { 643 1.4 christos if (m2 > 0) { 644 1.1 kleink mhi = lshift(mhi, m2); 645 1.4 christos if (mhi == NULL) 646 1.4 christos return NULL; 647 1.4 christos } 648 1.1 kleink 649 1.1 kleink /* Compute mlo -- check for special case 650 1.1 kleink * that d is a normalized power of 2. 651 1.1 kleink */ 652 1.1 kleink 653 1.1 kleink mlo = mhi; 654 1.1 kleink if (spec_case) { 655 1.1 kleink mhi = Balloc(mhi->k); 656 1.4 christos if (mhi == NULL) 657 1.4 christos return NULL; 658 1.1 kleink Bcopy(mhi, mlo); 659 1.1 kleink mhi = lshift(mhi, 1); 660 1.4 christos if (mhi == NULL) 661 1.4 christos return NULL; 662 1.1 kleink } 663 1.1 kleink 664 1.1 kleink for(i = 1;;i++) { 665 1.1 kleink dig = quorem(b,S) + '0'; 666 1.1 kleink /* Do we yet have the shortest decimal string 667 1.1 kleink * that will round to d? 668 1.1 kleink */ 669 1.1 kleink j = cmp(b, mlo); 670 1.1 kleink delta = diff(S, mhi); 671 1.4 christos if (delta == NULL) 672 1.4 christos return NULL; 673 1.2 christos jj1 = delta->sign ? 1 : cmp(b, delta); 674 1.1 kleink Bfree(delta); 675 1.1 kleink #ifndef ROUND_BIASED 676 1.2 christos if (jj1 == 0 && !mode && !(bits[0] & 1) && !rdir) { 677 1.1 kleink if (dig == '9') 678 1.1 kleink goto round_9_up; 679 1.1 kleink if (j <= 0) { 680 1.1 kleink if (b->wds > 1 || b->x[0]) 681 1.1 kleink inex = STRTOG_Inexlo; 682 1.1 kleink } 683 1.1 kleink else { 684 1.1 kleink dig++; 685 1.1 kleink inex = STRTOG_Inexhi; 686 1.1 kleink } 687 1.1 kleink *s++ = dig; 688 1.1 kleink goto ret; 689 1.1 kleink } 690 1.1 kleink #endif 691 1.2 christos if (j < 0 || (j == 0 && !mode 692 1.1 kleink #ifndef ROUND_BIASED 693 1.1 kleink && !(bits[0] & 1) 694 1.1 kleink #endif 695 1.2 christos )) { 696 1.1 kleink if (rdir && (b->wds > 1 || b->x[0])) { 697 1.1 kleink if (rdir == 2) { 698 1.1 kleink inex = STRTOG_Inexlo; 699 1.1 kleink goto accept; 700 1.1 kleink } 701 1.1 kleink while (cmp(S,mhi) > 0) { 702 1.1 kleink *s++ = dig; 703 1.1 kleink mhi1 = multadd(mhi, 10, 0); 704 1.4 christos if (mhi1 == NULL) 705 1.4 christos return NULL; 706 1.1 kleink if (mlo == mhi) 707 1.1 kleink mlo = mhi1; 708 1.1 kleink mhi = mhi1; 709 1.1 kleink b = multadd(b, 10, 0); 710 1.4 christos if (b == NULL) 711 1.4 christos return NULL; 712 1.1 kleink dig = quorem(b,S) + '0'; 713 1.1 kleink } 714 1.1 kleink if (dig++ == '9') 715 1.1 kleink goto round_9_up; 716 1.1 kleink inex = STRTOG_Inexhi; 717 1.1 kleink goto accept; 718 1.1 kleink } 719 1.2 christos if (jj1 > 0) { 720 1.1 kleink b = lshift(b, 1); 721 1.4 christos if (b == NULL) 722 1.4 christos return NULL; 723 1.2 christos jj1 = cmp(b, S); 724 1.5 christos #ifdef ROUND_BIASED 725 1.5 christos if (jj1 >= 0 /*)*/ 726 1.5 christos #else 727 1.2 christos if ((jj1 > 0 || (jj1 == 0 && dig & 1)) 728 1.5 christos #endif 729 1.1 kleink && dig++ == '9') 730 1.1 kleink goto round_9_up; 731 1.1 kleink inex = STRTOG_Inexhi; 732 1.1 kleink } 733 1.1 kleink if (b->wds > 1 || b->x[0]) 734 1.1 kleink inex = STRTOG_Inexlo; 735 1.1 kleink accept: 736 1.1 kleink *s++ = dig; 737 1.1 kleink goto ret; 738 1.1 kleink } 739 1.2 christos if (jj1 > 0 && rdir != 2) { 740 1.1 kleink if (dig == '9') { /* possible if i == 1 */ 741 1.1 kleink round_9_up: 742 1.1 kleink *s++ = '9'; 743 1.1 kleink inex = STRTOG_Inexhi; 744 1.1 kleink goto roundoff; 745 1.1 kleink } 746 1.1 kleink inex = STRTOG_Inexhi; 747 1.1 kleink *s++ = dig + 1; 748 1.1 kleink goto ret; 749 1.1 kleink } 750 1.1 kleink *s++ = dig; 751 1.1 kleink if (i == ilim) 752 1.1 kleink break; 753 1.1 kleink b = multadd(b, 10, 0); 754 1.4 christos if (b == NULL) 755 1.4 christos return NULL; 756 1.4 christos if (mlo == mhi) { 757 1.1 kleink mlo = mhi = multadd(mhi, 10, 0); 758 1.4 christos if (mlo == NULL) 759 1.4 christos return NULL; 760 1.4 christos } 761 1.1 kleink else { 762 1.1 kleink mlo = multadd(mlo, 10, 0); 763 1.4 christos if (mlo == NULL) 764 1.4 christos return NULL; 765 1.1 kleink mhi = multadd(mhi, 10, 0); 766 1.4 christos if (mhi == NULL) 767 1.4 christos return NULL; 768 1.1 kleink } 769 1.1 kleink } 770 1.1 kleink } 771 1.1 kleink else 772 1.1 kleink for(i = 1;; i++) { 773 1.1 kleink *s++ = dig = quorem(b,S) + '0'; 774 1.1 kleink if (i >= ilim) 775 1.1 kleink break; 776 1.1 kleink b = multadd(b, 10, 0); 777 1.4 christos if (b == NULL) 778 1.4 christos return NULL; 779 1.1 kleink } 780 1.1 kleink 781 1.1 kleink /* Round off last digit */ 782 1.1 kleink 783 1.1 kleink if (rdir) { 784 1.2 christos if (rdir == 2 || (b->wds <= 1 && !b->x[0])) 785 1.1 kleink goto chopzeros; 786 1.1 kleink goto roundoff; 787 1.1 kleink } 788 1.1 kleink b = lshift(b, 1); 789 1.4 christos if (b == NULL) 790 1.4 christos return NULL; 791 1.1 kleink j = cmp(b, S); 792 1.5 christos #ifdef ROUND_BIASED 793 1.5 christos if (j >= 0) 794 1.5 christos #else 795 1.5 christos if (j > 0 || (j == 0 && dig & 1)) 796 1.5 christos #endif 797 1.5 christos { 798 1.1 kleink roundoff: 799 1.1 kleink inex = STRTOG_Inexhi; 800 1.1 kleink while(*--s == '9') 801 1.1 kleink if (s == s0) { 802 1.1 kleink k++; 803 1.1 kleink *s++ = '1'; 804 1.1 kleink goto ret; 805 1.1 kleink } 806 1.1 kleink ++*s++; 807 1.1 kleink } 808 1.1 kleink else { 809 1.1 kleink chopzeros: 810 1.1 kleink if (b->wds > 1 || b->x[0]) 811 1.1 kleink inex = STRTOG_Inexlo; 812 1.1 kleink while(*--s == '0'){} 813 1.5 christos ++s; 814 1.1 kleink } 815 1.1 kleink ret: 816 1.1 kleink Bfree(S); 817 1.1 kleink if (mhi) { 818 1.1 kleink if (mlo && mlo != mhi) 819 1.1 kleink Bfree(mlo); 820 1.1 kleink Bfree(mhi); 821 1.1 kleink } 822 1.1 kleink ret1: 823 1.1 kleink Bfree(b); 824 1.1 kleink *s = 0; 825 1.1 kleink *decpt = k + 1; 826 1.1 kleink if (rve) 827 1.1 kleink *rve = s; 828 1.1 kleink *kindp |= inex; 829 1.1 kleink return s0; 830 1.1 kleink } 831