Skip to content

Instantly share code, notes, and snippets.

@LihuaWu
Last active August 29, 2015 14:17
Show Gist options
  • Save LihuaWu/08b00f239e7443006bb6 to your computer and use it in GitHub Desktop.
Save LihuaWu/08b00f239e7443006bb6 to your computer and use it in GitHub Desktop.
atof
//
// 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));
}
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