GCC Wikia
Advertisement

このページを編集する際は,編集に関する方針に従ってください.[]

概要[]

引数[]

  • char *str
  • const REAL_VALUE_TYPE *r_orig
  • size_t buf_size
  • size_t digits
  • int crop_trailing_zeros

実装[]

 1414 /* Render R as a decimal floating point constant.  Emit DIGITS significant
 1415    digits in the result, bounded by BUF_SIZE.  If DIGITS is 0, choose the
 1416    maximum for the representation.  If CROP_TRAILING_ZEROS, strip trailing
 1417    zeros.  */
1418 
1419 #define M_LOG10_2       0.30102999566398119521
1420 
1421 void
1422 real_to_decimal (char *str, const REAL_VALUE_TYPE *r_orig, size_t buf_size,
1423                  size_t digits, int crop_trailing_zeros)
1424 {
1425   const REAL_VALUE_TYPE *one, *ten;
1426   REAL_VALUE_TYPE r, pten, u, v;
1427   int dec_exp, cmp_one, digit;
1428   size_t max_digits;
1429   char *p, *first, *last;
1430   bool sign;
1431 

~

1432   r = *r_orig;
1433   switch (r.cl)
1434     {
1435     case [[rvc_zero>enum real_value_class]]:
1436       strcpy (str, (r.sign ? "-0.0" : "0.0"));
1437       return;
1438     case [[rvc_normal>enum real_value_class]]:
1439       break;
1440     case [[rvc_inf>enum real_value_class]]:
1441       strcpy (str, (r.sign ? "-Inf" : "+Inf"));
1442       return;
1443     case [[rvc_nan>enum real_value_class]]:
 1444       /* ??? Print the significand as well, if not canonical?  */
1445       strcpy (str, (r.sign ? "-NaN" : "+NaN"));
1446       return;
1447     default:
1448       gcc_unreachable ();
1449     }
1450 

~
*表示するけたの調整

 1451   /* Bound the number of digits printed by the size of the representation.  */
1452   max_digits = SIGNIFICAND_BITS * M_LOG10_2;
1453   if (digits == 0 || digits > max_digits)
1454     digits = max_digits;
1455 

~
*プリントされるときの文字列の長さを計算する

 1456   /* Estimate the decimal exponent, and compute the length of the string it
 1457      will print as.  Be conservative and add one to account for possible
 1458      overflow or rounding error.  */
1459   dec_exp = REAL_EXP (&r) * M_LOG10_2;
1460   for (max_digits = 1; dec_exp ; max_digits++)
1461     dec_exp /= 10;
1462 

~
*バッファのサイズによって文字列の長さが増える

 1463   /* Bound the number of digits printed by the size of the output buffer.  */
1464   max_digits = buf_size - 1 - 1 - 2 - max_digits - 1;
1465   gcc_assert (max_digits <= buf_size);
1466   if (digits > max_digits)
1467     digits = max_digits;
1468 

~

1469   one = real_digit (1);
1470   ten = ten_to_ptwo (0);
1471 
1472   sign = r.sign;
1473   r.sign = 0;
1474 
1475   dec_exp = 0;
1476   pten = *one;
1477 
1478   cmp_one = do_compare (&r, one, 0);

~
~
*数字が1より大きい

1479   if (cmp_one > 0)
1480     {
1481       int m;
1482 
 1483       /* Number is greater than one.  Convert significand to an integer
 1484          and strip trailing decimal zeros.  */
1485 
1486       u = r;
1487       SET_REAL_EXP (&u, SIGNIFICAND_BITS - 1);
1488 
 1489       /* Largest M, such that 10**2**M fits within SIGNIFICAND_BITS.  */
1490       m = floor_log2 (max_digits);
1491 
 1492       /* Iterate over the bits of the possible powers of 10 that might
 1493          be present in U and eliminate them.  That is, if we find that
 1494          10**2**M divides U evenly, keep the division and increase
 1495          DEC_EXP by 2**M.  */
1496       do
1497         {
1498           REAL_VALUE_TYPE t;
1499 
1500           do_divide (&t, &u, ten_to_ptwo (m));
1501           do_fix_trunc (&v, &t);
1502           if (cmp_significands (&v, &t) == 0)
1503             {
1504               u = t;
1505               dec_exp += 1 << m;
1506             }
1507         }
1508       while (--m >= 0);
1509 
 1510       /* Revert the scaling to integer that we performed earlier.  */
1511       SET_REAL_EXP (&u, REAL_EXP (&u) + REAL_EXP (&r)
1512                     - (SIGNIFICAND_BITS - 1));
1513       r = u;
1514 
 1515       /* Find power of 10.  Do this by dividing out 10**2**M when
 1516          this is larger than the current remainder.  Fill PTEN with
 1517          the power of 10 that we compute.  */
1518       if (REAL_EXP (&r) > 0)
1519         {
1520           m = floor_log2 ((int)(REAL_EXP (&r) * M_LOG10_2)) + 1;
1521           do
1522             {
1523               const REAL_VALUE_TYPE *ptentwo = ten_to_ptwo (m);
1524               if (do_compare (&u, ptentwo, 0) >= 0)
1525                 {
1526                   do_divide (&u, &u, ptentwo);
1527                   do_multiply (&pten, &pten, ptentwo);
1528                   dec_exp += 1 << m;
1529                 }
1530             }
1531           while (--m >= 0);
1532         }
1533       else
 1534         /* We managed to divide off enough tens in the above reduction
 1535            loop that we've now got a negative exponent.  Fall into the
 1536            less-than-one code to compute the proper value for PTEN.  */
1537         cmp_one = -1;
1538     }

~
*数字が1より小さい

1539   if (cmp_one < 0)
1540     {
1541       int m;
1542 
 1543       /* Number is less than one.  Pad significand with leading
 1544          decimal zeros.  */
1545 
1546       v = r;
1547       while (1)
1548         {
 1549           /* Stop if we'd shift bits off the bottom.  */
1550           if (v.sig[0] & 7)
1551             break;
1552 
1553           do_multiply (&u, &v, ten);
1554 
 1555           /* Stop if we're now >= 1.  */
1556           if (REAL_EXP (&u) > 0)
1557             break;
1558 
1559           v = u;
1560           dec_exp -= 1;
1561         }
1562       r = v;
1563 
 1564       /* Find power of 10.  Do this by multiplying in P=10**2**M when
 1565          the current remainder is smaller than 1/P.  Fill PTEN with the
 1566          power of 10 that we compute.  */
1567       m = floor_log2 (#&x28;int)(-REAL_EXP (&r) * M_LOG10_2)) + 1;
1568       do
1569         {
1570           const REAL_VALUE_TYPE *ptentwo = ten_to_ptwo (m);
1571           const REAL_VALUE_TYPE *ptenmtwo = ten_to_mptwo (m);
1572 
1573           if (do_compare (&v, ptenmtwo, 0) <= 0)
1574             {
1575               do_multiply (&v, &v, ptentwo);
1576               do_multiply (&pten, &pten, ptentwo);
1577               dec_exp -= 1 << m;
1578             }
1579         }
1580       while (--m >= 0);
1581 
 1582       /* Invert the positive power of 10 that we've collected so far.  */
1583       do_divide (&pten, one, &pten);
1584     }
1585 

~
~

1586   p = str;
1587   if (sign)
1588     *p++ = '-';
1589   first = p++;
1590 

~

 1591   /* At this point, PTEN should contain the nearest power of 10 smaller
 1592      than R, such that this division produces the first digit.
 1593 
 1594      Using a divide-step primitive that returns the complete integral
 1595      remainder avoids the rounding error that would be produced if
 1596      we were to use do_divide here and then simply multiply by 10 for
 1597      each subsequent digit.  */
1598 
1599   digit = rtd_divmod (&r, &pten);
1600 

*

 1601   /* Be prepared for error in that division via underflow ...  */
1602   if (digit == 0 && cmp_significand_0 (&r))
1603     {
 1604       /* Multiply by 10 and try again.  */
1605       do_multiply (&r, &r, ten);
1606       digit = rtd_divmod (&r, &pten);
1607       dec_exp -= 1;
1608       gcc_assert (digit != 0);
1609     }
1610 
 1611   /* ... or overflow.  */
1612   if (digit == 10)
1613     {
1614       *p++ = '1';
1615       if (--digits > 0)
1616         *p++ = '0';
1617       dec_exp += 1;
1618     }
1619   else
1620     {
1621       gcc_assert (digit <= 10);

*一桁文字列化

1622       *p++ = digit + '0';
1623     }
1624 

~
~
*以降の桁の生成

 1625   /* Generate subsequent digits.  */

* --digitsは(digits-1)と同じ意味でしか用いられていないようだ

1626   while (--digits > 0)
1627     {
1628       do_multiply (&r, &r, ten);
1629       digit = rtd_divmod (&r, &pten);
1630       *p++ = digit + '0';
1631     }
1632   last = p;
1633 

~
~
*小数点以下の四捨五入

 1634   /* Generate one more digit with which to do rounding.  */
1635   do_multiply (&r, &r, ten);
1636   digit = rtd_divmod (&r, &pten);
1637 

~

 1638   /* Round the result.  */
1639   if (digit == 5)
1640     {
 1641       /* Round to nearest.  If R is nonzero there are additional
 1642          nonzero digits to be extracted.  */
1643       if (cmp_significand_0 (&r))
1644         digit++;
 1645       /* Round to even.  */
1646       else if ((p[-1] - '0') & 1)
1647         digit++;
1648     }

~

1649   if (digit > 5)
1650     {
1651       while (p > first)
1652         {
1653           digit = *--p;
1654           if (digit == '9')
1655             *p = '0';
1656           else
1657             {
1658               *p = digit + 1;
1659               break;
1660             }
1661         }
1662 
 1663       /* Carry out of the first digit.  This means we had all 9's and
 1664          now have all 0's.  "Prepend" a 1 by overwriting the first 0.  */
1665       if (p == first)
1666         {
1667           first[1] = '1';
1668           dec_exp++;
1669         }
1670     }
1671 

~
~
*小数点の挿入

 1672   /* Insert the decimal point.  */
1673   first[0] = first[1];
1674   first[1] = '.';
1675 

*文字列の後ろから桁が0である間戻っていく

 1676   /* If requested, drop trailing zeros.  Never crop past "1.0".  */
1677   if (crop_trailing_zeros)
1678     while (last > first + 3 && last[-1] == '0')
1679       last--;
1680 

*後ろに指数を入れる

 1681   /* Append the exponent.  */
1682   sprintf (last, "e%+d", dec_exp);
1683 }


リンク元

Advertisement