strtoull関数はunsigned long long型を返す関数ですが、strtoul関数とほとんど内容は同じですので、具体的な解説は割愛します。strtoul関数の実装のうち、unsigned longの部分をunsigned long longに、ULONG_MAXの部分をULLONG_MAXに読み替えれば、strtoull関数になると思います。
int _space_sign(const char *s, const char **endptr);
unsigned long strtoul(const char * __restrict__ s, char ** __restrict__ endptr, int radix) { unsigned long result;
if (_space_sign(s, (const char**)&s) != 0) --s; // '-'の位置まで戻す
if (s[0] == '0') { ++s; if ((s[1] | 0x20) == 'x') { if (radix == 0 || radix == 16) { ++s; radix = 16; } } else if (radix == 0) radix = 8; } else if (radix == 0) radix = 10;
int c; for (result = 0; c = tolower((unsigned char)*s), isdigit(c) || ('a' <= c && c <= 'z'); s++) { int d = isdigit(c) ? c - '0' : c - 'a' + 10; if (d >= radix) break; if (result > (ULONG_MAX - d) / radix) { errno = ERANGE; result = ULONG_MAX; } else { result = result * radix + d; } }
int _space_sign(const char *s, const char **endptr);
long strtol(const char * __restrict__ s, char ** __restrict__ endptr, int radix) { int sign = _space_sign(s, (const char**)&s); long result;
if (s[0] == '0') { ++s; if ((s[1] | 0x20) == 'x') { if (radix == 0 || radix == 16) { ++s; radix = 16; } } else if (radix == 0) radix = 8; } else if (radix == 0) radix = 10;
int c; for (result = 0; c = tolower((unsigned char)*s), isdigit(c) || ('a' <= c && c <= 'z'); s++) { int d = isdigit(c) ? c - '0' : c - 'a' + 10; if (d >= radix) break; if (result > (LONG_MAX - d - sign) / radix) { errno = ERANGE; result = sign ? LONG_MIN : LONG_MAX; } else { result = result * radix + d; } }