mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 18:31:55 -04:00
Better handling of nan/infinity. Previously, these weren't working on Windows in config strings.
This commit is contained in:
parent
cd79de19b2
commit
515f93a0b8
@ -16,11 +16,11 @@
|
|||||||
// see float.h
|
// see float.h
|
||||||
#define FPU_CONTROLWORD_WRITEMASK 0xFFFFF // if you look at defn of _CW_DEFAULT, all settings fall within 0xFFFFF
|
#define FPU_CONTROLWORD_WRITEMASK 0xFFFFF // if you look at defn of _CW_DEFAULT, all settings fall within 0xFFFFF
|
||||||
#define FPU_CONTROLWORD_NEW_SETTING _CW_DEFAULT
|
#define FPU_CONTROLWORD_NEW_SETTING _CW_DEFAULT
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: csqrt
|
// Function: csqrt
|
||||||
// Description:
|
// Description:
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
INLINE float
|
INLINE float
|
||||||
csqrt(float v) {
|
csqrt(float v) {
|
||||||
@ -29,7 +29,7 @@ csqrt(float v) {
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: csin
|
// Function: csin
|
||||||
// Description:
|
// Description:
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
INLINE float
|
INLINE float
|
||||||
csin(float v) {
|
csin(float v) {
|
||||||
@ -38,7 +38,7 @@ csin(float v) {
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: ccos
|
// Function: ccos
|
||||||
// Description:
|
// Description:
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
INLINE float
|
INLINE float
|
||||||
ccos(float v) {
|
ccos(float v) {
|
||||||
@ -47,7 +47,7 @@ ccos(float v) {
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: ctan
|
// Function: ctan
|
||||||
// Description:
|
// Description:
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
INLINE float ctan(float v) {
|
INLINE float ctan(float v) {
|
||||||
return tanf(v);
|
return tanf(v);
|
||||||
@ -55,7 +55,7 @@ INLINE float ctan(float v) {
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: csincos
|
// Function: csincos
|
||||||
// Description:
|
// Description:
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
INLINE void
|
INLINE void
|
||||||
csincos(float v, float *sin_result, float *cos_result) {
|
csincos(float v, float *sin_result, float *cos_result) {
|
||||||
@ -80,7 +80,7 @@ csincos(float v, float *sin_result, float *cos_result) {
|
|||||||
// Function: csin_over_x
|
// Function: csin_over_x
|
||||||
// Description: Computes sin(x) / x, well-behaved as x approaches 0.
|
// Description: Computes sin(x) / x, well-behaved as x approaches 0.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
INLINE float
|
INLINE float
|
||||||
csin_over_x(float v) {
|
csin_over_x(float v) {
|
||||||
if (1.0f + v * v == 1.0f) {
|
if (1.0f + v * v == 1.0f) {
|
||||||
return 1.0f;
|
return 1.0f;
|
||||||
@ -91,7 +91,7 @@ csin_over_x(float v) {
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: cabs
|
// Function: cabs
|
||||||
// Description:
|
// Description:
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
INLINE float
|
INLINE float
|
||||||
cabs(float v) {
|
cabs(float v) {
|
||||||
@ -100,7 +100,7 @@ cabs(float v) {
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: catan
|
// Function: catan
|
||||||
// Description:
|
// Description:
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
INLINE float
|
INLINE float
|
||||||
catan(float v) {
|
catan(float v) {
|
||||||
@ -109,7 +109,7 @@ catan(float v) {
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: catan2
|
// Function: catan2
|
||||||
// Description:
|
// Description:
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
INLINE float
|
INLINE float
|
||||||
catan2(float y, float x) {
|
catan2(float y, float x) {
|
||||||
@ -118,7 +118,7 @@ catan2(float y, float x) {
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: casin
|
// Function: casin
|
||||||
// Description:
|
// Description:
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
INLINE float
|
INLINE float
|
||||||
casin(float v) {
|
casin(float v) {
|
||||||
@ -127,7 +127,7 @@ casin(float v) {
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: cacos
|
// Function: cacos
|
||||||
// Description:
|
// Description:
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
INLINE float
|
INLINE float
|
||||||
cacos(float v) {
|
cacos(float v) {
|
||||||
@ -147,7 +147,7 @@ cmod(float x, float y) {
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: cpow
|
// Function: cpow
|
||||||
// Description:
|
// Description:
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
INLINE float
|
INLINE float
|
||||||
cpow(float x, float y) {
|
cpow(float x, float y) {
|
||||||
@ -157,7 +157,7 @@ cpow(float x, float y) {
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: cfloor
|
// Function: cfloor
|
||||||
// Description:
|
// Description:
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
INLINE double
|
INLINE double
|
||||||
cfloor(double f) {
|
cfloor(double f) {
|
||||||
@ -169,13 +169,13 @@ cfloor(double f) {
|
|||||||
_controlfp(saved_fpu_control_word,FPU_CONTROLWORD_WRITEMASK);
|
_controlfp(saved_fpu_control_word,FPU_CONTROLWORD_WRITEMASK);
|
||||||
return retval;
|
return retval;
|
||||||
#else
|
#else
|
||||||
return floor(f);
|
return floor(f);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: cceil
|
// Function: cceil
|
||||||
// Description:
|
// Description:
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
INLINE double
|
INLINE double
|
||||||
cceil(double f) {
|
cceil(double f) {
|
||||||
@ -187,7 +187,7 @@ cceil(double f) {
|
|||||||
_controlfp(saved_fpu_control_word,FPU_CONTROLWORD_WRITEMASK);
|
_controlfp(saved_fpu_control_word,FPU_CONTROLWORD_WRITEMASK);
|
||||||
return retval;
|
return retval;
|
||||||
#else
|
#else
|
||||||
return ceil(f);
|
return ceil(f);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -202,7 +202,7 @@ cfrac(double f) {
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: csqrt
|
// Function: csqrt
|
||||||
// Description:
|
// Description:
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
INLINE double
|
INLINE double
|
||||||
csqrt(double v) {
|
csqrt(double v) {
|
||||||
@ -211,7 +211,7 @@ csqrt(double v) {
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: csin
|
// Function: csin
|
||||||
// Description:
|
// Description:
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
INLINE double
|
INLINE double
|
||||||
csin(double v) {
|
csin(double v) {
|
||||||
@ -220,7 +220,7 @@ csin(double v) {
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: ccos
|
// Function: ccos
|
||||||
// Description:
|
// Description:
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
INLINE double
|
INLINE double
|
||||||
ccos(double v) {
|
ccos(double v) {
|
||||||
@ -229,7 +229,7 @@ ccos(double v) {
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: ctan
|
// Function: ctan
|
||||||
// Description:
|
// Description:
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
INLINE double
|
INLINE double
|
||||||
ctan(double v) {
|
ctan(double v) {
|
||||||
@ -238,7 +238,7 @@ ctan(double v) {
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: csincos
|
// Function: csincos
|
||||||
// Description:
|
// Description:
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
INLINE void
|
INLINE void
|
||||||
csincos(double v, double *sin_result, double *cos_result) {
|
csincos(double v, double *sin_result, double *cos_result) {
|
||||||
@ -262,7 +262,7 @@ csincos(double v, double *sin_result, double *cos_result) {
|
|||||||
// Function: csin_over_x
|
// Function: csin_over_x
|
||||||
// Description: Computes sin(x) / x, well-behaved as x approaches 0.
|
// Description: Computes sin(x) / x, well-behaved as x approaches 0.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
INLINE double
|
INLINE double
|
||||||
csin_over_x(double v) {
|
csin_over_x(double v) {
|
||||||
if (1.0 + v * v == 1.0) {
|
if (1.0 + v * v == 1.0) {
|
||||||
return 1.0;
|
return 1.0;
|
||||||
@ -273,7 +273,7 @@ csin_over_x(double v) {
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: cabs
|
// Function: cabs
|
||||||
// Description:
|
// Description:
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
INLINE double
|
INLINE double
|
||||||
cabs(double v) {
|
cabs(double v) {
|
||||||
@ -282,7 +282,7 @@ cabs(double v) {
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: catan
|
// Function: catan
|
||||||
// Description:
|
// Description:
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
INLINE double
|
INLINE double
|
||||||
catan(double v) {
|
catan(double v) {
|
||||||
@ -291,7 +291,7 @@ catan(double v) {
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: catan2
|
// Function: catan2
|
||||||
// Description:
|
// Description:
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
INLINE double
|
INLINE double
|
||||||
catan2(double y, double x) {
|
catan2(double y, double x) {
|
||||||
@ -300,7 +300,7 @@ catan2(double y, double x) {
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: casin
|
// Function: casin
|
||||||
// Description:
|
// Description:
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
INLINE double
|
INLINE double
|
||||||
casin(double v) {
|
casin(double v) {
|
||||||
@ -309,7 +309,7 @@ casin(double v) {
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: cacos
|
// Function: cacos
|
||||||
// Description:
|
// Description:
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
INLINE double
|
INLINE double
|
||||||
cacos(double v) {
|
cacos(double v) {
|
||||||
@ -329,7 +329,7 @@ cmod(double x, double y) {
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: cpow
|
// Function: cpow
|
||||||
// Description:
|
// Description:
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
INLINE double
|
INLINE double
|
||||||
cpow(double x, double y) {
|
cpow(double x, double y) {
|
||||||
@ -338,7 +338,7 @@ cpow(double x, double y) {
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: cpow
|
// Function: cpow
|
||||||
// Description:
|
// Description:
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
INLINE int
|
INLINE int
|
||||||
cpow(int x, int y) {
|
cpow(int x, int y) {
|
||||||
@ -360,43 +360,73 @@ cpow(int x, int y) {
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: cnan
|
// Function: cnan
|
||||||
// Description:
|
// Description:
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
INLINE bool
|
INLINE bool
|
||||||
cnan(double v) {
|
cnan(double v) {
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
return (std::isnan(v) != 0);
|
return std::isnan(v);
|
||||||
#else
|
#else
|
||||||
return (_isnan(v) != 0);
|
return (_isnan(v) != 0);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: cinf
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE bool
|
||||||
|
cinf(double v) {
|
||||||
|
#ifndef _WIN32
|
||||||
|
return std::isinf(v);
|
||||||
|
#else
|
||||||
|
return (_isnan(v) == 0 && _finite(v) == 0);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: make_nan
|
// Function: make_nan
|
||||||
// Description:
|
// Description:
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
INLINE float
|
INLINE float
|
||||||
make_nan(float) {
|
make_nan(float) {
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
return nanf("");
|
return nanf("");
|
||||||
#else
|
#else
|
||||||
return numeric_limits<float>::quiet_NaN();
|
return std::numeric_limits<float>::quiet_NaN();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: make_nan
|
// Function: make_nan
|
||||||
// Description:
|
// Description:
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
INLINE double
|
INLINE double
|
||||||
make_nan(double) {
|
make_nan(double) {
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
return nan("");
|
return nan("");
|
||||||
#else
|
#else
|
||||||
return numeric_limits<double>::quiet_NaN();
|
return std::numeric_limits<double>::quiet_NaN();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: make_inf
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE float
|
||||||
|
make_inf(float) {
|
||||||
|
return std::numeric_limits<float>::infinity();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: make_inf
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE double
|
||||||
|
make_inf(double) {
|
||||||
|
return std::numeric_limits<double>::infinity();
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: cmod
|
// Function: cmod
|
||||||
|
@ -68,13 +68,17 @@ INLINE int cpow(int x, int y);
|
|||||||
// or infinity.
|
// or infinity.
|
||||||
INLINE bool cnan(double v);
|
INLINE bool cnan(double v);
|
||||||
|
|
||||||
// Returns NaN.
|
// Returns true if the number is infinity.
|
||||||
|
INLINE bool cinf(double v);
|
||||||
|
|
||||||
|
// Return NaN and infinity, respectively.
|
||||||
INLINE float make_nan(float);
|
INLINE float make_nan(float);
|
||||||
INLINE double make_nan(double);
|
INLINE double make_nan(double);
|
||||||
|
INLINE float make_inf(float);
|
||||||
|
INLINE double make_inf(double);
|
||||||
|
|
||||||
INLINE int cmod(int x, int y);
|
INLINE int cmod(int x, int y);
|
||||||
|
|
||||||
#include "cmath.I"
|
#include "cmath.I"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -17,6 +17,9 @@
|
|||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#define strncasecmp _strnicmp
|
||||||
|
#endif
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: pstrtod
|
// Function: pstrtod
|
||||||
@ -45,67 +48,100 @@ pstrtod(const char *nptr, char **endptr) {
|
|||||||
double value = 0.0;
|
double value = 0.0;
|
||||||
|
|
||||||
if (isalpha(*p)) {
|
if (isalpha(*p)) {
|
||||||
// For special cases like "inf" and "nan", pass these up to the
|
// Windows' implementation of strtod doesn't support "inf" or
|
||||||
// system implementation of strtod.
|
// "nan", so check for those here.
|
||||||
return strtod(nptr, endptr);
|
if (strncasecmp(p, "inf", 3) == 0) {
|
||||||
}
|
p += 3;
|
||||||
|
if (strncasecmp(p, "inity", 5) == 0) {
|
||||||
|
p += 5;
|
||||||
|
}
|
||||||
|
value = std::numeric_limits<double>::infinity();
|
||||||
|
|
||||||
|
} else if (strncasecmp(p, "nan", 3) == 0) {
|
||||||
|
p += 3;
|
||||||
|
|
||||||
|
if (*p == 's' || *p == 'S') {
|
||||||
|
value = std::numeric_limits<double>::signaling_NaN();
|
||||||
|
++p;
|
||||||
|
} else {
|
||||||
|
if (*p == 'q' || *p == 'Q') {
|
||||||
|
++p;
|
||||||
|
}
|
||||||
|
value = std::numeric_limits<double>::quiet_NaN();
|
||||||
|
}
|
||||||
|
|
||||||
|
// It is optionally possible to include a character sequence
|
||||||
|
// between parentheses after "nan", to be passed to the new
|
||||||
|
// nan() function. Since it isn't supported universally, we
|
||||||
|
// will only accept a pair of empty parentheses.
|
||||||
|
if (strncmp(p, "()", 2) == 0) {
|
||||||
|
p += 2;
|
||||||
|
}
|
||||||
|
|
||||||
// Start reading decimal digits to the left of the decimal point.
|
|
||||||
bool found_digits = false;
|
|
||||||
while (isdigit(*p)) {
|
|
||||||
value = (value * 10.0) + (*p - '0');
|
|
||||||
found_digits = true;
|
|
||||||
++p;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*p == '.') {
|
|
||||||
++p;
|
|
||||||
// Read decimal digits to the right of the decimal point.
|
|
||||||
double multiplicand = 0.1;
|
|
||||||
while (isdigit(*p)) {
|
|
||||||
value += (*p - '0') * multiplicand;
|
|
||||||
++p;
|
|
||||||
found_digits = true;
|
|
||||||
multiplicand *= 0.1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!found_digits) {
|
|
||||||
// Not a valid float.
|
|
||||||
if (endptr != NULL) {
|
|
||||||
*endptr = (char *)nptr;
|
|
||||||
}
|
|
||||||
return 0.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tolower(*p) == 'e') {
|
|
||||||
// There's an exponent.
|
|
||||||
++p;
|
|
||||||
|
|
||||||
char esign = '+';
|
|
||||||
if (*p == '+' || *p == '-') {
|
|
||||||
esign = *p;
|
|
||||||
++p;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Start reading decimal digits to the left of the decimal point.
|
|
||||||
double evalue = 0.0;
|
|
||||||
while (isdigit(*p)) {
|
|
||||||
evalue = (evalue * 10.0) + (*p - '0');
|
|
||||||
++p;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (esign == '-') {
|
|
||||||
value /= pow(evalue, 10.0);
|
|
||||||
} else {
|
} else {
|
||||||
value *= pow(evalue, 10.0);
|
// Pass it up to the system implementation of strtod;
|
||||||
|
// perhaps it knows how to deal with this string.
|
||||||
|
return strtod(nptr, endptr);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
} else {
|
||||||
|
// Start reading decimal digits to the left of the decimal point.
|
||||||
|
bool found_digits = false;
|
||||||
|
while (isdigit(*p)) {
|
||||||
|
value = (value * 10.0) + (*p - '0');
|
||||||
|
found_digits = true;
|
||||||
|
++p;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*p == '.') {
|
||||||
|
++p;
|
||||||
|
// Read decimal digits to the right of the decimal point.
|
||||||
|
double multiplicand = 0.1;
|
||||||
|
while (isdigit(*p)) {
|
||||||
|
value += (*p - '0') * multiplicand;
|
||||||
|
++p;
|
||||||
|
found_digits = true;
|
||||||
|
multiplicand *= 0.1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!found_digits) {
|
||||||
|
// Not a valid float.
|
||||||
|
if (endptr != NULL) {
|
||||||
|
*endptr = (char *)nptr;
|
||||||
|
}
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tolower(*p) == 'e') {
|
||||||
|
// There's an exponent.
|
||||||
|
++p;
|
||||||
|
|
||||||
|
char esign = '+';
|
||||||
|
if (*p == '+' || *p == '-') {
|
||||||
|
esign = *p;
|
||||||
|
++p;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start reading decimal digits to the left of the decimal point.
|
||||||
|
double evalue = 0.0;
|
||||||
|
while (isdigit(*p)) {
|
||||||
|
evalue = (evalue * 10.0) + (*p - '0');
|
||||||
|
++p;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (esign == '-') {
|
||||||
|
value /= pow(evalue, 10.0);
|
||||||
|
} else {
|
||||||
|
value *= pow(evalue, 10.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (sign == '-') {
|
if (sign == '-') {
|
||||||
value = -value;
|
value = -value;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (endptr != NULL) {
|
if (endptr != NULL) {
|
||||||
*endptr = (char *)p;
|
*endptr = (char *)p;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user