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

📄 num_get_float.cpp

📁 使用QT为linux 下的mplayer写的一个新的gui
💻 CPP
📖 第 1 页 / 共 3 页
字号:
  uint64 prodhi, prodlo;        /* 128b product */
  int exp_hi, exp_lo;           /* exp = exp_hi*32 + exp_lo */
  int hi, lo, tlo, thi;         /* offsets in power of ten table */
  int norm;                     /* number of bits of normalization */
  int num_hi;                   /* number of high exponent powers */

  bexp = 0;
  if (exp > 0) {                 /* split exponent */
    exp_lo = exp;
    exp_hi = 0;
    if (exp_lo > 27) {
      exp_lo++;
      while (exp_lo > 27) {
        exp_hi++;
        exp_lo -= 28;
      }
    }
    tlo = TEN_1;
    thi = TEN_27;
    num_hi = NUM_HI_P;
  }
  else if (exp < 0) {
    exp_lo = exp;
    exp_hi = 0;
    while (exp_lo < 0) {
      exp_hi++;
      exp_lo += 28;
    }
    tlo = TEN_1;
    thi = TEN_M28;
    num_hi = NUM_HI_N;
  }
  else {                        /* no scaling needed */
    return;
  }
  while (exp_hi) {               /* scale */
    hi = (min) (exp_hi, num_hi);    /* only a few large powers of 10 */
    exp_hi -= hi;               /* could iterate in extreme case */
    hi += thi-1;
    _Stl_mult64(p, _Stl_tenpow[hi], prodhi, prodlo);
    _Stl_norm_and_round(p, norm, prodhi, prodlo);
    bexp += _Stl_twoexp[hi] - norm;
  }
  if (exp_lo) {
    lo = tlo + exp_lo -1;
    _Stl_mult64(p, _Stl_tenpow[lo], prodhi, prodlo);
    _Stl_norm_and_round(p, norm, prodhi, prodlo);
    bexp += _Stl_twoexp[lo] - norm;
  }

  return;
}

// First argument is a buffer of values from 0 to 9, NOT ascii.
// Second argument is number of digits in buffer, 1 <= digits <= 17.
// Third argument is base-10 exponent.

#if defined (__SC__) || defined (__MRC__)

//*TY 04/06/2000 - powermac's 68K emulator utilizes apple's SANE floating point, which is not compatible with IEEE format.
_STLP_MOVE_TO_STD_NAMESPACE
_STLP_END_NAMESPACE

#  include <fp.h>

_STLP_BEGIN_NAMESPACE
_STLP_MOVE_TO_PRIV_NAMESPACE

static inline double _Stl_atod(char *buffer, int ndigit, int dexp) {
  decimal d;  // ref. inside macintosh powerpc numerics p.9-13

  d.sgn = 0;
  d.exp = dexp;
  d.sig.length = ndigit;
  for (int i = 0; i < ndigit; ++i) {
    d.sig.text[i] = buffer[i] + '0';
  }
  return dec2num(&d);
}

#else  /* IEEE representation */

#  if !defined (__linux__)
static double _Stl_atod(char *buffer, int ndigit, int dexp) {
  uint64 value;         /* Value develops as follows:
                                 * 1) decimal digits as an integer
                                 * 2) left adjusted fraction
                                 * 3) right adjusted fraction
                                 * 4) exponent and fraction
                                 */

  uint32 guard;         /* First guard bit */
  uint64 rest;          /* Remaining guard bits */

  int bexp;             /* binary exponent */
  int nzero;            /* number of non-zero bits */
  int sexp;             /* scaling exponent */

  char *bufferend;              /* pointer to char after last digit */

  /* Check for zero and treat it as a special case */
  if (buffer == 0){
    return 0.0;
  }

  /* Convert the decimal digits to a binary integer. */

  bufferend = buffer + ndigit;
  value = 0;

  while (buffer < bufferend) {
    value *= 10;
    value += *buffer++;
  }

  /* Check for zero and treat it as a special case */
  if (value == 0) {
    return 0.0;
  }

  /* Normalize value */
  bexp = 64;                    /* convert from 64b int to fraction */

  /* Count number of non-zeroes in value */
  nzero = 0;
  if ((value >> 32) != 0) { nzero  = 32; }    //*TY 03/25/2000 - added explicit comparison to zero to avoid uint64 to bool conversion operator
  if ((value >> (16 + nzero)) != 0) { nzero += 16; }
  if ((value >> ( 8 + nzero)) != 0) { nzero +=  8; }
  if ((value >> ( 4 + nzero)) != 0) { nzero +=  4; }
  if ((value >> ( 2 + nzero)) != 0) { nzero +=  2; }
  if ((value >> ( 1 + nzero)) != 0) { nzero +=  1; }
  if ((value >> (     nzero)) != 0) { nzero +=  1; }

  /* Normalize */
  value <<= /*(uint64)*/ (64 - nzero);    //*TY 03/25/2000 - removed extraneous cast to uint64
  bexp -= 64 - nzero;

  /* At this point we have a 64b fraction and a binary exponent
   * but have yet to incorporate the decimal exponent.
   */

  /* multiply by 10^dexp */
  _Stl_tenscale(value, dexp, sexp);
  bexp += sexp;

  if (bexp <= -1022) {          /* HI denorm or underflow */
    bexp += 1022;
    if (bexp < -53) {          /* guaranteed underflow */
      value = 0;
    }
    else {                      /* denorm or possible underflow */
      int lead0 = 12 - bexp;          /* 12 sign and exponent bits */

      /* we must special case right shifts of more than 63 */
      if (lead0 > 64) {
        rest = value;
        guard = 0;
        value = 0;
      }
      else if (lead0 == 64) {
        rest = value & ((ULL(1)<< 63)-1);
#if !defined(__SC__)
        guard = (uint32) ((value>> 63) & 1 );
#else
        guard = to_ulong((value>> 63) & 1 );   //*TY 03/25/2000 - use member function instead of problematic conversion operator utilization
#endif
        value = 0;
      }
      else {
        rest = value & (((ULL(1) << lead0)-1)-1);
#if !defined(__SC__)
        guard = (uint32) (((value>> lead0)-1) & 1);
#else     //*TY 03/25/2000 -
        guard = to_ulong(((value>> lead0)-1) & 1);
#endif    //*TY 03/25/2000 -
        value >>= /*(uint64)*/ lead0; /* exponent is zero */
      }

      /* Round */
      if (guard && ((value & 1) || rest) ) {
        ++value;
        if (value == (ULL(1) << 52)) { /* carry created normal number */
          value = 0;
          _Stl_set_exponent(value, 1);
        }
      }
    }
  }
  else {                        /* not zero or denorm */
    /* Round to 53 bits */
    rest = value & (1<<10)-1;
    value >>= 10;
#if !defined(__SC__)
    guard = (uint32) value & 1;
#else    //*TY 03/25/2000 -
    guard = to_ulong(value & 1);
#endif
    value >>= 1;

    /*  value&1 guard   rest    Action
     *
     *  dc      0       dc      none
     *  1       1       dc      round
     *  0       1       0       none
     *  0       1       !=0     round
     */
    if (guard) {
      if (((value&1)!=0) || (rest!=0)) {
        ++value;                        /* round */
        if ((value >> 53) != 0) {       /* carry all the way across */
          value >>= 1;          /* renormalize */
          ++bexp;
        }
      }
    }
    /*
     * Check for overflow
     * IEEE Double Precision Format
     * (From Table 7-8 of Kane and Heinrich)
     *
     * Fraction bits               52
     * Emax                     +1023
     * Emin                     -1022
     * Exponent bias            +1023
     * Exponent bits               11
     * Integer bit             hidden
     * Total width in bits         64
     */

    if (bexp > 1024) {          /* overflow */
      return numeric_limits<double>::infinity();
    }
    else {                      /* value is normal */
      value &= ~(ULL(1) << 52);   /* hide hidden bit */
      _Stl_set_exponent(value, bexp + 1022); /* add bias */
    }
  }

  _STLP_STATIC_ASSERT(sizeof(value) == sizeof(double))
  return *((double *) &value);
}

#  else // __linux__

static double _Stl_atod(char *buffer, int ndigit, int dexp) {
  ieee754_double v;

  char *bufferend;              /* pointer to char after last digit */

  /* Check for zero and treat it as a special case */

  if (buffer == 0) {
    return 0.0;
  }

  /* Convert the decimal digits to a binary integer. */

  bufferend = buffer + ndigit;
  _ll vv;
  vv.i64 = 0L;

  while (buffer < bufferend) {
    vv.i64 *= 10;
    vv.i64 += *buffer++;
  }

  /* Check for zero and treat it as a special case */
  if (vv.i64 == 0){
    return 0.0;
  }

  /* Normalize value */
  int bexp = 64;                    /* convert from 64b int to fraction */

  /* Count number of non-zeroes in value */
  int nzero = 0;
  if ((vv.i64 >> 32) !=0 ) { nzero  = 32; }    //*TY 03/25/2000 - added explicit comparison to zero to avoid uint64 to bool conversion operator
  if ((vv.i64 >> (16 + nzero)) != 0) { nzero += 16; }
  if ((vv.i64 >> ( 8 + nzero)) != 0) { nzero +=  8; }
  if ((vv.i64 >> ( 4 + nzero)) != 0) { nzero +=  4; }
  if ((vv.i64 >> ( 2 + nzero)) != 0) { nzero +=  2; }
  if ((vv.i64 >> ( 1 + nzero)) != 0) { nzero +=  1; }
  if ((vv.i64 >> (     nzero)) != 0) { nzero +=  1; }

  /* Normalize */
  nzero = 64 - nzero;
  vv.i64 <<= nzero;    //*TY 03/25/2000 - removed extraneous cast to uint64
  bexp -= nzero;

  /* At this point we have a 64b fraction and a binary exponent
   * but have yet to incorporate the decimal exponent.
   */

  /* multiply by 10^dexp */
  int sexp;
  _Stl_tenscale(vv.i64, dexp, sexp);
  bexp += sexp;

  if (bexp <= -1022) {          /* HI denorm or underflow */
    bexp += 1022;
    if (bexp < -53) {           /* guaranteed underflow */
      vv.i64 = 0;
    }
    else {                      /* denorm or possible underflow */
      int lead0;
      uint64_t rest;
      uint32_t guard;

      lead0 = 12-bexp;          /* 12 sign and exponent bits */

      /* we must special case right shifts of more than 63 */
      if (lead0 > 64) {
        rest = vv.i64;
        guard = 0;
        vv.i64 = 0;
      }
      else if (lead0 == 64) {
        rest = vv.i64 & ((ULL(1) << 63)-1);
#if !defined(__SC__)
        guard = (uint32) ((vv.i64 >> 63) & 1 );
#else
        guard = to_ulong((vv.i64 >> 63) & 1 );   //*TY 03/25/2000 - use member function instead of problematic conversion operator utilization
#endif
        vv.i64 = 0;
      }
      else {
        rest = vv.i64 & (((ULL(1) << lead0)-1)-1);
#if !defined(__SC__)
        guard = (uint32) (((vv.i64 >> lead0)-1) & 1);
#else     //*TY 03/25/2000 -
        guard = to_ulong(((vv.i64 >> lead0)-1) & 1);
#endif    //*TY 03/25/2000 -

⌨️ 快捷键说明

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