~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to mystrings/dtoa.c

  • Committer: Monty Taylor
  • Date: 2008-09-15 17:24:04 UTC
  • Revision ID: monty@inaugust.com-20080915172404-ygh6hiyu0q7qpa9x
Removed strndup calls.

Show diffs side-by-side

added added

removed removed

Lines of Context:
130
130
    if (len <= decpt)
131
131
      *dst++= '.';
132
132
    
133
 
    for (i= precision - cmax(0, (len - decpt)); i > 0; i--)
 
133
    for (i= precision - max(0, (len - decpt)); i > 0; i--)
134
134
      *dst++= '0';
135
135
  }
136
136
  
219
219
  if (x < 0.)
220
220
    width--;
221
221
 
222
 
  res= dtoa(x, 4, type == MY_GCVT_ARG_DOUBLE ? width : cmin(width, FLT_DIG),
 
222
  res= dtoa(x, 4, type == MY_GCVT_ARG_DOUBLE ? width : min(width, FLT_DIG),
223
223
            &decpt, &sign, &end, buf, sizeof(buf));
224
224
  if (decpt == DTOA_OVERFLOW)
225
225
  {
528
528
  file.
529
529
*/
530
530
 
 
531
/*
 
532
  #define Honor_FLT_ROUNDS if FLT_ROUNDS can assume the values 2 or 3
 
533
       and dtoa should round accordingly.
 
534
  #define Check_FLT_ROUNDS if FLT_ROUNDS can assume the values 2 or 3
 
535
       and Honor_FLT_ROUNDS is not #defined.
 
536
 
 
537
  TODO: check if we can get rid of the above two
 
538
*/
 
539
 
531
540
typedef int32_t Long;
532
541
typedef uint32_t ULong;
533
542
typedef int64_t LLong;
583
592
#endif
584
593
#endif /*Flt_Rounds*/
585
594
 
 
595
#ifdef Honor_FLT_ROUNDS
 
596
#define Rounding rounding
 
597
#undef Check_FLT_ROUNDS
 
598
#define Check_FLT_ROUNDS
 
599
#else
 
600
#define Rounding Flt_Rounds
 
601
#endif
 
602
 
586
603
#define rounded_product(a,b) a*= b
587
604
#define rounded_quotient(a,b) a/= b
588
605
 
1314
1331
#ifdef SET_INEXACT
1315
1332
  int inexact, oldinexact;
1316
1333
#endif
 
1334
#ifdef Honor_FLT_ROUNDS
 
1335
  int rounding;
 
1336
#endif
1317
1337
  Stack_alloc alloc;
1318
1338
 
1319
1339
  c= 0;
1471
1491
  }
1472
1492
  bd0= 0;
1473
1493
  if (nd <= DBL_DIG
 
1494
#ifndef Honor_FLT_ROUNDS
 
1495
    && Flt_Rounds == 1
 
1496
#endif
1474
1497
      )
1475
1498
  {
1476
1499
    if (!e)
1479
1502
    {
1480
1503
      if (e <= Ten_pmax)
1481
1504
      {
 
1505
#ifdef Honor_FLT_ROUNDS
 
1506
        /* round correctly FLT_ROUNDS = 2 or 3 */
 
1507
        if (sign)
 
1508
        {
 
1509
          rv= -rv;
 
1510
          sign= 0;
 
1511
        }
 
1512
#endif
1482
1513
        /* rv = */ rounded_product(dval(rv), tens[e]);
1483
1514
        goto ret;
1484
1515
      }
1489
1520
          A fancier test would sometimes let us do
1490
1521
          this for larger i values.
1491
1522
        */
 
1523
#ifdef Honor_FLT_ROUNDS
 
1524
        /* round correctly FLT_ROUNDS = 2 or 3 */
 
1525
        if (sign)
 
1526
        {
 
1527
          rv= -rv;
 
1528
          sign= 0;
 
1529
        }
 
1530
#endif
1492
1531
        e-= i;
1493
1532
        dval(rv)*= tens[i];
1494
1533
        /* rv = */ rounded_product(dval(rv), tens[e]);
1498
1537
#ifndef Inaccurate_Divide
1499
1538
    else if (e >= -Ten_pmax)
1500
1539
    {
 
1540
#ifdef Honor_FLT_ROUNDS
 
1541
      /* round correctly FLT_ROUNDS = 2 or 3 */
 
1542
      if (sign)
 
1543
      {
 
1544
        rv= -rv;
 
1545
        sign= 0;
 
1546
      }
 
1547
#endif
1501
1548
      /* rv = */ rounded_quotient(dval(rv), tens[-e]);
1502
1549
      goto ret;
1503
1550
    }
1511
1558
    oldinexact= get_inexact();
1512
1559
#endif
1513
1560
  scale= 0;
 
1561
#ifdef Honor_FLT_ROUNDS
 
1562
  if ((rounding= Flt_Rounds) >= 2)
 
1563
  {
 
1564
    if (sign)
 
1565
      rounding= rounding == 2 ? 0 : 2;
 
1566
    else
 
1567
      if (rounding != 2)
 
1568
        rounding= 0;
 
1569
  }
 
1570
#endif
1514
1571
 
1515
1572
  /* Get starting approximation = rv * 10**e1 */
1516
1573
 
1525
1582
 ovfl:
1526
1583
        *error= EOVERFLOW;
1527
1584
        /* Can't trust HUGE_VAL */
 
1585
#ifdef Honor_FLT_ROUNDS
 
1586
        switch (rounding)
 
1587
        {
 
1588
        case 0: /* toward 0 */
 
1589
        case 3: /* toward -infinity */
 
1590
          word0(rv)= Big0;
 
1591
          word1(rv)= Big1;
 
1592
          break;
 
1593
        default:
 
1594
          word0(rv)= Exp_mask;
 
1595
          word1(rv)= 0;
 
1596
        }
 
1597
#else /*Honor_FLT_ROUNDS*/
1528
1598
        word0(rv)= Exp_mask;
1529
1599
        word1(rv)= 0;
 
1600
#endif /*Honor_FLT_ROUNDS*/
1530
1601
#ifdef SET_INEXACT
1531
1602
        /* set overflow bit */
1532
1603
        dval(rv0)= 1e300;
1622
1693
    else
1623
1694
      bd2-= bbe;
1624
1695
    bs2= bb2;
 
1696
#ifdef Honor_FLT_ROUNDS
 
1697
    if (rounding != 1)
 
1698
      bs2++;
 
1699
#endif
1625
1700
    j= bbe - scale;
1626
1701
    i= j + bbbits - 1;  /* logb(rv) */
1627
1702
    if (i < Emin)  /* denormal */
1659
1734
    dsign= delta->sign;
1660
1735
    delta->sign= 0;
1661
1736
    i= cmp(delta, bs);
 
1737
#ifdef Honor_FLT_ROUNDS
 
1738
    if (rounding != 1)
 
1739
    {
 
1740
      if (i < 0)
 
1741
      {
 
1742
        /* Error is less than an ulp */
 
1743
        if (!delta->x[0] && delta->wds <= 1)
 
1744
        {
 
1745
          /* exact */
 
1746
#ifdef SET_INEXACT
 
1747
          inexact= 0;
 
1748
#endif
 
1749
          break;
 
1750
        }
 
1751
        if (rounding)
 
1752
        {
 
1753
          if (dsign)
 
1754
          {
 
1755
            adj= 1.;
 
1756
            goto apply_adj;
 
1757
          }
 
1758
        }
 
1759
        else if (!dsign)
 
1760
        {
 
1761
          adj= -1.;
 
1762
          if (!word1(rv) && !(word0(rv) & Frac_mask))
 
1763
          {
 
1764
            y= word0(rv) & Exp_mask;
 
1765
            if (!scale || y > 2*P*Exp_msk1)
 
1766
            {
 
1767
              delta= lshift(delta,Log2P);
 
1768
              if (cmp(delta, bs) <= 0)
 
1769
              adj= -0.5;
 
1770
            }
 
1771
          }
 
1772
 apply_adj:
 
1773
          if (scale && (y= word0(rv) & Exp_mask) <= 2 * P * Exp_msk1)
 
1774
            word0(adj)+= (2 * P + 1) * Exp_msk1 - y;
 
1775
          dval(rv)+= adj * ulp(dval(rv));
 
1776
        }
 
1777
        break;
 
1778
      }
 
1779
      adj= ratio(delta, bs);
 
1780
      if (adj < 1.)
 
1781
        adj= 1.;
 
1782
      if (adj <= 0x7ffffffe)
 
1783
      {
 
1784
        /* adj = rounding ? ceil(adj) : floor(adj); */
 
1785
        y= adj;
 
1786
        if (y != adj)
 
1787
        {
 
1788
          if (!((rounding >> 1) ^ dsign))
 
1789
            y++;
 
1790
          adj= y;
 
1791
        }
 
1792
      }
 
1793
      if (scale && (y= word0(rv) & Exp_mask) <= 2 * P * Exp_msk1)
 
1794
        word0(adj)+= (2 * P + 1) * Exp_msk1 - y;
 
1795
      adj*= ulp(dval(rv));
 
1796
      if (dsign)
 
1797
        dval(rv)+= adj;
 
1798
      else
 
1799
        dval(rv)-= adj;
 
1800
      goto cont;
 
1801
    }
 
1802
#endif /*Honor_FLT_ROUNDS*/
1662
1803
 
1663
1804
    if (i < 0)
1664
1805
    {
1765
1906
    {
1766
1907
      aadj*= 0.5;
1767
1908
      aadj1= dsign ? aadj : -aadj;
 
1909
#ifdef Check_FLT_ROUNDS
 
1910
      switch (Rounding)
 
1911
      {
 
1912
      case 2: /* towards +infinity */
 
1913
        aadj1-= 0.5;
 
1914
        break;
 
1915
      case 0: /* towards 0 */
 
1916
      case 3: /* towards -infinity */
 
1917
        aadj1+= 0.5;
 
1918
      }
 
1919
#else
1768
1920
      if (Flt_Rounds == 0)
1769
1921
        aadj1+= 0.5;
 
1922
#endif /*Check_FLT_ROUNDS*/
1770
1923
    }
1771
1924
    y= word0(rv) & Exp_mask;
1772
1925
 
1983
2136
          1 ==> like 0, but with Steele & White stopping rule;
1984
2137
                e.g. with IEEE P754 arithmetic , mode 0 gives
1985
2138
                1e23 whereas mode 1 gives 9.999999999999999e22.
1986
 
          2 ==> cmax(1,ndigits) significant digits.  This gives a
 
2139
          2 ==> max(1,ndigits) significant digits.  This gives a
1987
2140
                return value similar to that of ecvt, except
1988
2141
                that trailing zeros are suppressed.
1989
2142
          3 ==> through ndigits past the decimal point.  This
1993
2146
          4,5 ==> similar to 2 and 3, respectively, but (in
1994
2147
                round-nearest mode) with the tests of mode 0 to
1995
2148
                possibly return a shorter string that rounds to d.
 
2149
                With IEEE arithmetic and compilation with
 
2150
                -DHonor_FLT_ROUNDS, modes 4 and 5 behave the same
 
2151
                as modes 2 and 3 when FLT_ROUNDS != 1.
1996
2152
          6-9 ==> Debugging modes similar to mode - 4:  don't try
1997
2153
                fast floating-point estimate (if applicable).
1998
2154
 
2011
2167
  Bigint *b, *b1, *delta, *mlo = NULL, *mhi, *S;
2012
2168
  double d2, ds, eps;
2013
2169
  char *s, *s0;
 
2170
#ifdef Honor_FLT_ROUNDS
 
2171
  int rounding;
 
2172
#endif
2014
2173
  Stack_alloc alloc;
2015
2174
  
2016
2175
  alloc.begin= alloc.free= buf;
2039
2198
    return res;
2040
2199
  }
2041
2200
  
 
2201
#ifdef Honor_FLT_ROUNDS
 
2202
  if ((rounding= Flt_Rounds) >= 2)
 
2203
  {
 
2204
    if (*sign)
 
2205
      rounding= rounding == 2 ? 0 : 2;
 
2206
    else
 
2207
      if (rounding != 2)
 
2208
        rounding= 0;
 
2209
  }
 
2210
#endif
2042
2211
 
2043
2212
  b= d2b(dval(d), &be, &bbits, &alloc);
2044
2213
  if ((i= (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1))))
2122
2291
  if (mode < 0 || mode > 9)
2123
2292
    mode= 0;
2124
2293
 
 
2294
#ifdef Check_FLT_ROUNDS
 
2295
  try_quick= Rounding == 1;
 
2296
#else
2125
2297
  try_quick= 1;
 
2298
#endif
2126
2299
 
2127
2300
  if (mode > 5)
2128
2301
  {
2157
2330
  }
2158
2331
  s= s0= dtoa_alloc(i, &alloc);
2159
2332
 
 
2333
#ifdef Honor_FLT_ROUNDS
 
2334
  if (mode > 1 && rounding != 1)
 
2335
    leftright= 0;
 
2336
#endif
 
2337
 
2160
2338
  if (ilim >= 0 && ilim <= Quick_max && try_quick)
2161
2339
  {
2162
2340
    /* Try to get by with floating-point arithmetic. */
2286
2464
    {
2287
2465
      L= (Long)(dval(d) / ds);
2288
2466
      dval(d)-= L*ds;
 
2467
#ifdef Check_FLT_ROUNDS
 
2468
      /* If FLT_ROUNDS == 2, L will usually be high by 1 */
 
2469
      if (dval(d) < 0)
 
2470
      {
 
2471
        L--;
 
2472
        dval(d)+= ds;
 
2473
      }
 
2474
#endif
2289
2475
      *s++= '0' + (int)L;
2290
2476
      if (!dval(d))
2291
2477
      {
2293
2479
      }
2294
2480
      if (i == ilim)
2295
2481
      {
 
2482
#ifdef Honor_FLT_ROUNDS
 
2483
        if (mode > 1)
 
2484
        {
 
2485
          switch (rounding) {
 
2486
          case 0: goto ret1;
 
2487
          case 2: goto bump_up;
 
2488
          }
 
2489
        }
 
2490
#endif
2296
2491
        dval(d)+= dval(d);
2297
2492
        if (dval(d) > ds || (dval(d) == ds && L & 1))
2298
2493
        {
2354
2549
 
2355
2550
  spec_case= 0;
2356
2551
  if ((mode < 2 || leftright)
 
2552
#ifdef Honor_FLT_ROUNDS
 
2553
      && rounding == 1
 
2554
#endif
2357
2555
     )
2358
2556
  {
2359
2557
    if (!word1(d) && !(word0(d) & Bndry_mask) &&
2447
2645
      j1= delta->sign ? 1 : cmp(b, delta);
2448
2646
      Bfree(delta, &alloc);
2449
2647
      if (j1 == 0 && mode != 1 && !(word1(d) & 1)
 
2648
#ifdef Honor_FLT_ROUNDS
 
2649
          && rounding >= 1
 
2650
#endif
2450
2651
         )
2451
2652
      {
2452
2653
        if (dig == '9')
2462
2663
        {
2463
2664
          goto accept_dig;
2464
2665
        }
 
2666
#ifdef Honor_FLT_ROUNDS
 
2667
        if (mode > 1)
 
2668
          switch (rounding) {
 
2669
          case 0: goto accept_dig;
 
2670
          case 2: goto keep_dig;
 
2671
          }
 
2672
#endif /*Honor_FLT_ROUNDS*/
2465
2673
        if (j1 > 0)
2466
2674
        {
2467
2675
          b= lshift(b, 1, &alloc);
2476
2684
      }
2477
2685
      if (j1 > 0)
2478
2686
      {
 
2687
#ifdef Honor_FLT_ROUNDS
 
2688
        if (!rounding)
 
2689
          goto accept_dig;
 
2690
#endif
2479
2691
        if (dig == '9')
2480
2692
        { /* possible if i == 1 */
2481
2693
round_9_up:
2485
2697
        *s++= dig + 1;
2486
2698
        goto ret;
2487
2699
      }
 
2700
#ifdef Honor_FLT_ROUNDS
 
2701
keep_dig:
 
2702
#endif
2488
2703
      *s++= dig;
2489
2704
      if (i == ilim)
2490
2705
        break;
2513
2728
 
2514
2729
  /* Round off last digit */
2515
2730
 
 
2731
#ifdef Honor_FLT_ROUNDS
 
2732
  switch (rounding) {
 
2733
  case 0: goto trimzeros;
 
2734
  case 2: goto roundoff;
 
2735
  }
 
2736
#endif
2516
2737
  b= lshift(b, 1, &alloc);
2517
2738
  j= cmp(b, S);
2518
2739
  if (j > 0 || (j == 0 && dig & 1))
2529
2750
  }
2530
2751
  else
2531
2752
  {
 
2753
#ifdef Honor_FLT_ROUNDS
 
2754
trimzeros:
 
2755
#endif
2532
2756
    while (*--s == '0');
2533
2757
    s++;
2534
2758
  }