Created
May 28, 2015 03:33
-
-
Save mansourmoufid/9e0cb994067e618f97f2 to your computer and use it in GitHub Desktop.
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
#include <assert.h> | |
#include <stddef.h> | |
#include <stdio.h> | |
#include <string.h> | |
#include <limits.h> | |
#include "str2long.h" | |
#if LONG_MAX == 9223372036854775807UL | |
#define LONG_MAX_DIGITS 19 | |
#else | |
#define LONG_MAX_DIGITS 10 | |
#endif | |
static inline int | |
isdigit(const char x) | |
{ | |
if (x >= 0x30 && x <= 0x39) { | |
return 1; | |
} | |
return 0; | |
} | |
static int | |
verify(const char *str) | |
{ | |
size_t len, i; | |
if (str == NULL) { | |
return 1; | |
} | |
len = strlen(str); | |
if (len == 0) { | |
return 1; | |
} | |
if (len > LONG_MAX_DIGITS + 1) { | |
return 1; | |
} | |
i = 0; | |
if (str[0] == '-') { | |
if (isdigit(str[1]) == 0) { | |
return 1; | |
} | |
i = 1; | |
} | |
for (; i < len; i++) { | |
if (isdigit(str[i]) == 0) { | |
return 1; | |
} | |
} | |
return 0; | |
} | |
static inline unsigned long int | |
ord(const char x) | |
{ | |
return (unsigned long int) x - 0x30; | |
} | |
static inline size_t | |
min(const size_t x, const size_t y) | |
{ | |
if (x < y) { | |
return x; | |
} | |
return y; | |
} | |
extern int error; | |
long int | |
str2long(const char *str) | |
{ | |
int sign; | |
unsigned long int result, base, bound, x; | |
size_t len, i, j; | |
if (verify(str) != 0) { | |
error = 1; | |
return 0; | |
} | |
len = strlen(str); | |
i = 0; | |
result = 0; | |
sign = 1; | |
bound = LONG_MAX; | |
if (str[0] == '-') { | |
sign = -1; | |
bound += 1; | |
i = 1; | |
} | |
base = 1; | |
for (j = 0; j < len - i - 1; j++) { | |
base *= 10; | |
} | |
while (i < min(len, LONG_MAX_DIGITS - 1)) { | |
x = base * ord(str[i]); | |
result += x; | |
base /= 10; | |
i++; | |
} | |
while (i < len) { | |
x = base * ord(str[i]); | |
if (result > bound - x) { | |
error = 1; | |
return 0; | |
} | |
result += x; | |
base /= 10; | |
i++; | |
} | |
return (long int) result * sign; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment