⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dtoa.cc

📁 早期freebsd实现
💻 CC
字号:
/* Copyright (C) 1990 Free Software Foundation    written by Doug Lea (dl@rocky.oswego.edu)This file is part of the GNU C++ Library.  This library is freesoftware; you can redistribute it and/or modify it under the terms ofthe GNU Library General Public License as published by the FreeSoftware Foundation; either version 2 of the License, or (at youroption) any later version.  This library is distributed in the hopethat it will be useful, but WITHOUT ANY WARRANTY; without even theimplied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULARPURPOSE.  See the GNU Library General Public License for more details.You should have received a copy of the GNU Library General PublicLicense along with this library; if not, write to the Free SoftwareFoundation, 675 Mass Ave, Cambridge, MA 02139, USA.*/#ifdef __GNUG__#pragma implementation#endif#include <builtin.h>#include <math.h>#include <values.h>#include <AllocRing.h>extern AllocRing _libgxx_fmtq;// OBSOLETE ROUTINE!char* dtoa(double fpnum,  char cvt, int width, int prec){  // set up workspace  // max possible digits <= those need to show all of prec + exp  // <= ceil(log10(HUGE)) plus space for null, etc.  const int worksiz = int((M_LN2 / M_LN10) * DMAXEXP) + 8;   // for fractional part  char  fwork[worksiz];  char* fw = fwork;  // for integer part  char  iwork[worksiz];  char* iworkend = &iwork[sizeof(iwork) - 1];  char* iw = iworkend;  *iw = 0;  // for exponent part  const int eworksiz = int(M_LN2 * _DEXPLEN) + 8;  char  ework[eworksiz];  char* eworkend = &ework[sizeof(ework) - 1];  char* ew = eworkend;  *ew = 0;#if (_IEEE != 0)  if (isinf(fpnum))  {    char* inffmt = (char *) _libgxx_fmtq.alloc(5);    char* inffmtp = inffmt;    if (fpnum < 0)      *inffmtp++ = '-';    strcpy(inffmtp, "Inf");    return inffmt;  }  if (isnan(fpnum))  {    char* nanfmt = (char *) _libgxx_fmtq.alloc(4);    strcpy(nanfmt, "NaN");    return nanfmt;  }#endif  // grab sign & make non-negative  int is_neg = fpnum < 0;  if (is_neg) fpnum = -fpnum;  // precision matters  if (prec > worksiz - 2) // can't have more prec than supported    prec = worksiz - 2;    double powprec;  if (prec == 6)    powprec = 1.0e6;  else    powprec = pow(10.0, (long) prec);  double rounder = 0.5 / powprec;  int f_fmt = cvt == 'f' ||    ((cvt == 'g') && (fpnum == 0.0 || (fpnum >= 1e-4 && fpnum < powprec)));  int iwidth = 0;  int fwidth = 0;  int ewidth = 0;  if (f_fmt)  // fixed format  {    double ipart;    double fpart = modf(fpnum, &ipart);    // convert fractional part    if (fpart >= rounder || cvt != 'g')    {      fpart += rounder;      if (fpart >= 1.0)      {        ipart += 1.0;        fpart -= 1.0;      }      double ffpart = fpart;      double ifpart;      for (int i = 0; i < prec; ++i)      {        ffpart = modf(ffpart * 10.0, &ifpart);        *fw++ = '0' + int(ifpart);        ++fwidth;      }      if (cvt == 'g')  // inhibit trailing zeroes if g-fmt      {        for (char* p = fw - 1; p >= fwork && *p == '0'; --p)        {          *p = 0;          --fwidth;        }      }    }    // convert integer part    if (ipart == 0.0)    {      if (cvt != 'g' || fwidth < prec || fwidth < width)      {        *--iw = '0'; ++iwidth;      }    }    else if (ipart <= double(MAXLONG)) // a useful speedup    {      long li = long(ipart);      while (li != 0)      {        *--iw = '0' + (li % 10);        li = li / 10;        ++iwidth;      }    }    else // the slow way    {      while (ipart > 0.5)      {        double ff = modf(ipart / 10.0, &ipart);        ff = (ff + 0.05) * 10.0;        *--iw = '0' + int(ff);        ++iwidth;      }    }    // g-fmt: kill part of frac if prec/width exceeded    if (cvt == 'g')    {      int m = prec;      if (m < width)        m = width;      int adj = iwidth + fwidth - m;      if (adj > fwidth)        adj = fwidth;      if (adj > 0)      {        for (char* f = &fwork[fwidth-1]; f >= fwork && adj > 0; --adj, --f)        {          --fwidth;          char ch = *f;          *f = 0;          if (ch > '5') // properly round: unavoidable propagation          {            int carry = 1;            for (char* p = f - 1; p >= fwork && carry; --p)            {              ++*p;              if (*p > '9')                *p = '0';              else                carry = 0;            }            if (carry)            {              for (p = iworkend - 1; p >= iw && carry; --p)              {                ++*p;                if (*p > '9')                  *p = '0';                else                  carry = 0;              }              if (carry)              {                *--iw = '1';                ++iwidth;                --adj;              }            }          }        }      }    }                }  else  // e-fmt  {        // normalize    int exp = 0;    while (fpnum >= 10.0)    {      fpnum *= 0.1;      ++exp;    }    double almost_one = 1.0 - rounder;    while (fpnum > 0.0 && fpnum < almost_one)    {      fpnum *= 10.0;      --exp;    }        double ipart;    double fpart = modf(fpnum, &ipart);    if (cvt == 'g')     // used up one digit for int part...    {      --prec;      powprec /= 10.0;      rounder = 0.5 / powprec;    }    // convert fractional part -- almost same as above    if (fpart >= rounder || cvt != 'g')    {      fpart += rounder;      if (fpart >= 1.0)      {        fpart -= 1.0;        ipart += 1.0;        if (ipart >= 10.0)        {          ++exp;          ipart /= 10.0;          fpart /= 10.0;        }      }      double ffpart = fpart;      double ifpart;      for (int i = 0; i < prec; ++i)      {        ffpart = modf(ffpart * 10.0, &ifpart);        *fw++ = '0' + int(ifpart);        ++fwidth;      }      if (cvt == 'g')  // inhibit trailing zeroes if g-fmt      {        for (char* p = fw - 1; p >= fwork && *p == '0'; --p)        {          *p = 0;          --fwidth;        }      }    }        // convert exponent    char eneg = exp < 0;    if (eneg) exp = - exp;    while (exp > 0)    {      *--ew = '0' + (exp % 10);      exp /= 10;      ++ewidth;    }    while (ewidth < 2)  // ensure at least 2 zeroes    {      *--ew = '0';      ++ewidth;    }    *--ew = eneg ? '-' : '+';    *--ew = 'e';    ewidth += 2;    // convert the one-digit integer part    *--iw = '0' + int(ipart);    ++iwidth;      }  // arrange everything in returned string  int showdot = cvt != 'g' || fwidth > 0;  int fmtwidth = is_neg + iwidth + showdot + fwidth + ewidth;    int pad = width - fmtwidth;  if (pad < 0) pad = 0;    char* fmtbase = (char *) _libgxx_fmtq.alloc(fmtwidth + pad + 1);  char* fmt = fmtbase;    for (int i = 0; i < pad; ++i) *fmt++ = ' ';    if (is_neg) *fmt++ = '-';    for (i = 0; i < iwidth; ++i) *fmt++ = *iw++;    if (showdot)  {    *fmt++ = '.';    fw = fwork;    for (i = 0; i < fwidth; ++i) *fmt++ = *fw++;  }    for (i = 0; i < ewidth; ++i) *fmt++ = *ew++;    *fmt = 0;    return fmtbase;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -