Last active
August 29, 2015 14:17
-
-
Save LihuaWu/08b00f239e7443006bb6 to your computer and use it in GitHub Desktop.
atof
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// Simple and fast atof (ascii to float) function. | |
// | |
// - Executes about 5x faster than standard MSCRT library atof(). | |
// - An attractive alternative if the number of calls is in the millions. | |
// - Assumes input is a proper integer, fraction, or scientific format. | |
// - Matches library atof() to 15 digits (except at extreme exponents). | |
// - Follows atof() precedent of essentially no error checking. | |
// | |
// 09-May-2009 Tom Van Baak (tvb) www.LeapSecond.com | |
// | |
#define white_space(c) ((c) == ' ' || (c) == '\t') | |
#define valid_digit(c) ((c) >= '0' && (c) <= '9') | |
double atof (const char *p) | |
{ | |
int frac; | |
double sign, value, scale; | |
// Skip leading white space, if any. | |
while (white_space(*p) ) { | |
p += 1; | |
} | |
// Get sign, if any. | |
sign = 1.0; | |
if (*p == '-') { | |
sign = -1.0; | |
p += 1; | |
} else if (*p == '+') { | |
p += 1; | |
} | |
// Get digits before decimal point or exponent, if any. | |
for (value = 0.0; valid_digit(*p); p += 1) { | |
value = value * 10.0 + (*p - '0'); | |
} | |
// Get digits after decimal point, if any. | |
if (*p == '.') { | |
double pow10 = 10.0; | |
p += 1; | |
while (valid_digit(*p)) { | |
value += (*p - '0') / pow10; | |
pow10 *= 10.0; | |
p += 1; | |
} | |
} | |
// Handle exponent, if any. | |
frac = 0; | |
scale = 1.0; | |
if ((*p == 'e') || (*p == 'E')) { | |
unsigned int expon; | |
// Get sign of exponent, if any. | |
p += 1; | |
if (*p == '-') { | |
frac = 1; | |
p += 1; | |
} else if (*p == '+') { | |
p += 1; | |
} | |
// Get digits of exponent, if any. | |
for (expon = 0; valid_digit(*p); p += 1) { | |
expon = expon * 10 + (*p - '0'); | |
} | |
if (expon > 308) expon = 308; | |
// Calculate scaling factor. | |
while (expon >= 50) { scale *= 1E50; expon -= 50; } | |
while (expon >= 8) { scale *= 1E8; expon -= 8; } | |
while (expon > 0) { scale *= 10.0; expon -= 1; } | |
} | |
// Return signed and scaled floating point result. | |
return sign * (frac ? (value / scale) : (value * scale)); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
float stof(const char* s){ | |
float rez = 0, fact = 1; | |
if (*s == '-'){ | |
s++; | |
fact = -1; | |
}; | |
for (int point_seen = 0; *s; s++){ | |
if (*s == '.'){ | |
point_seen = 1; | |
continue; | |
}; | |
int d = *s - '0'; | |
if (d >= 0 && d <= 9){ | |
if (point_seen) fact /= 10.0f; | |
rez = rez * 10.0f + (float)d; | |
}; | |
}; | |
return rez * fact; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment