📄 num_get_float.cpp
字号:
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 + -