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

📄 num_get_float.cpp

📁 使用QT为linux 下的mplayer写的一个新的gui
💻 CPP
📖 第 1 页 / 共 3 页
字号:
        vv.i64 >>= /*(uint64)*/ lead0; /* exponent is zero */
      }

      /* Round */
      if (guard && ( (vv.i64 & 1) || rest)) {
        vv.i64++;
        if (vv.i64 == (ULL(1) << 52)) { /* carry created normal number */
          v.ieee.mantissa0 = 0;
          v.ieee.mantissa1 = 0;
          v.ieee.negative = 0;
          v.ieee.exponent = 1;
          return v.d;
        }
      }
    }
  }
  else {                        /* not zero or denorm */
    /* Round to 53 bits */
    uint64_t rest = vv.i64 & (1<<10)-1;
    vv.i64 >>= 10;
#if !defined(__SC__)
    uint32_t guard = (uint32) vv.i64 & 1;
#else    //*TY 03/25/2000 -
    uint32_t guard = to_ulong(vv.i64 & 1);
#endif
    vv.i64 >>= 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 (((vv.i64&1)!=0) || (rest!=0)) {
        vv.i64++;                        /* round */
        if ((vv.i64>>53)!=0) {         /* carry all the way across */
          vv.i64 >>= 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 */
      vv.i64 &= ~(ULL(1) << 52);   /* hide hidden bit */
      v.ieee.mantissa0 = vv.i32.hi;
      v.ieee.mantissa1 = vv.i32.lo;
      v.ieee.negative = 0;
      v.ieee.exponent = bexp + 1022;
      return v.d;
    }
  }

  v.ieee.mantissa0 = vv.i32.hi;
  v.ieee.mantissa1 = vv.i32.lo;
  v.ieee.negative = 0;
  v.ieee.exponent = 0;

  return v.d;
}
#  endif // __linux__

#endif

static double _Stl_string_to_double(const char *s) {
  const int max_digits = 17;
  unsigned c;
  unsigned Negate, decimal_point;
  char *d;
  int exp;
  double x;
  int dpchar;
  char digits[max_digits];

  // Skip leading whitespace, if any.
  const ctype<char>& ct = use_facet<ctype<char> >(locale::classic());
  while (c = *s++, ct.is(ctype_base::space, char(c))) {}

  /* process sign */
  Negate = 0;
  if (c == '+') {
    c = *s++;
  }
  else if (c == '-') {
    Negate = 1;
    c = *s++;
  }
  d = digits;
  dpchar = '.' - '0';
  decimal_point = 0;
  exp = 0;
  for (;;) {
    c -= '0';
    if (c < 10) {
      if (d == digits + max_digits) {
        /* ignore more than 17 digits, but adjust exponent */
        exp += (decimal_point ^ 1);
      }
      else {
        if (c == 0 && d == digits) {
          /* ignore leading zeros */
        }
        else {
          *d++ = (char) c;
        }
        exp -= decimal_point;
      }
    }
    else if (c == (unsigned int) dpchar && !decimal_point) {    /* INTERNATIONAL */
      decimal_point = 1;
    }
    else {
      break;
    }
    c = *s++;
  }
  /* strtod cant return until it finds the end of the exponent */
  if (d == digits) {
    return 0.0;
  }

  if (c == 'e'-'0' || c == 'E'-'0') {
    register unsigned negate_exp = 0;
    register int e = 0;
    c = *s++;
    if (c == '+' || c == ' ') {
      c = *s++;
    }
    else if (c == '-') {
      negate_exp = 1;
      c = *s++;
    }
    if (c -= '0', c < 10) {
      do {
        if (e <= 340)
          e = e * 10 + (int)c;
        else break;
        c = *s++;
      }
      while (c -= '0', c < 10);
      if (negate_exp) {
        e = -e;
      }
      if (e < -340 || e > 340)
        exp = e;
      else
        exp += e;
    }
  }

  if (exp < -340) {
    x = 0;
  }
  else if (exp > 308) {
    x = numeric_limits<double>::infinity();
  }
  else {
    /* let _Stl_atod diagnose under- and over-flows */
    /* if the input was == 0.0, we have already returned,
       so retval of +-Inf signals OVERFLOW, 0.0 UNDERFLOW
    */
    x = _Stl_atod(digits, (int)(d - digits), exp);
  }
  if (Negate) {
    x = -x;
  }
  return x;
}


#if !defined (_STLP_NO_LONG_DOUBLE)
/*
 * __string_to_long_double is just lifted from atold, the difference being
 * that we just use '.' for the decimal point, rather than let it
 * be taken from the current C locale, which of course is not accessible
 * to us.
 */

static long double
_Stl_string_to_long_double(const char * s) {
  const int max_digits = 34;
  register unsigned c;
  register unsigned Negate, decimal_point;
  register char *d;
  register int exp;
  long double x;
  register int dpchar;
  char digits[max_digits];

  const ctype<char>& ct = use_facet<ctype<char> >(locale::classic());
  while (c = *s++, ct.is(ctype_base::space, char(c)))
    ;

  /* process sign */
  Negate = 0;
  if (c == '+') {
    c = *s++;
  }
  else if (c == '-') {
    Negate = 1;
    c = *s++;
  }

  d = digits;
  dpchar = '.' - '0';
  decimal_point = 0;
  exp = 0;

  for (;;) {
    c -= '0';
    if (c < 10) {
      if (d == digits+max_digits) {
        /* ignore more than 34 digits, but adjust exponent */
        exp += (decimal_point ^ 1);
      }
      else {
        if (c == 0 && d == digits) {
          /* ignore leading zeros */
          ;
        }
        else {
          *d++ = (char)c;
        }
        exp -= decimal_point;
      }
    }
    else if ((char)c == dpchar && !decimal_point) {    /* INTERNATIONAL */
      decimal_point = 1;
    }
    else {
      break;
    }
    c = *s++;
  } /* for */

  if (d == digits) {
    return 0.0L;
  }
  if (c == 'e'-'0' || c == 'E'-'0') {
    register unsigned negate_exp = 0;
    register int e = 0;
    c = *s++;
    if (c == '+' || c == ' ') {
      c = *s++;
    }
    else if (c == '-') {
      negate_exp = 1;
      c = *s++;
    }
    if (c -= '0', c < 10) {
      do {
        if (e <= 340)
          e = e * 10 + c;
        else break;
        c = *s++;
      }
      while (c -= '0', c < 10);
      if (negate_exp) {
        e = -e;
      }
      if (e < -(323+max_digits) || e > 308)
        exp = e;
      else
        exp += e;
    }
  }

  if (exp < -(324+max_digits)) {
    x = 0;
  }
  else if (exp > 308) {
    x =  numeric_limits<long double>::infinity();
  }
  else {
    /* let _Stl_atod diagnose under- and over-flows */
    /* if the input was == 0.0, we have already returned,
           so retval of +-Inf signals OVERFLOW, 0.0 UNDERFLOW
        */

    //    x = _Stl_atod (digits, (int)(d - digits), exp); // TEMPORARY!!:1
    double tmp = _Stl_atod (digits, (int)(d - digits), exp); // TEMPORARY!!:1
    x = tmp == numeric_limits<double>::infinity()
      ? numeric_limits<long double>::infinity()
      : tmp;
  }

  if (Negate) {
    x = -x;
  }

  return x;
}
#endif

void _STLP_CALL
__string_to_float(const __iostring& v, float& val)
{ val = (float)_Stl_string_to_double(v.c_str()); }

void _STLP_CALL
__string_to_float(const __iostring& v, double& val)
{ val = _Stl_string_to_double(v.c_str()); }

#if !defined (_STLP_NO_LONG_DOUBLE)
void _STLP_CALL
__string_to_float(const __iostring& v, long double& val)
{ val = _Stl_string_to_long_double(v.c_str()); }
#endif

_STLP_MOVE_TO_STD_NAMESPACE
_STLP_END_NAMESPACE

// Local Variables:
// mode:C++
// End:

⌨️ 快捷键说明

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