Skip to content

Instantly share code, notes, and snippets.

@mansourmoufid
Created May 28, 2015 03:33
Show Gist options
  • Save mansourmoufid/9e0cb994067e618f97f2 to your computer and use it in GitHub Desktop.
Save mansourmoufid/9e0cb994067e618f97f2 to your computer and use it in GitHub Desktop.
#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