Created
December 1, 2017 11:26
-
-
Save gamerforEA/0b0216d605345c7d8e0e6a48ae641f66 to your computer and use it in GitHub Desktop.
C++ integer parser (based on JVM sources)
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 <climits> | |
#include <cstring> | |
#define MIN_RADIX 2 | |
#define MAX_RADIX 36 | |
int digitVal(char ch, int radix) { | |
if (radix < MIN_RADIX || radix > MAX_RADIX) | |
return -1; | |
if (ch >= 'A' && ch <= 'Z' && ch < radix + 'A' - 10) | |
return ch - 'A' + 10; | |
if (ch >= 'a' && ch <= 'z' && ch < radix + 'a' - 10) | |
return ch - 'a' + 10; | |
if (ch >= '0' && ch <= '9' && ch < radix + '0') | |
return ch - '0'; | |
return -1; | |
} | |
bool tryParseInt(const char *s, int radix, int *resultPtr) { | |
if (s == nullptr || radix < MIN_RADIX || radix > MAX_RADIX) | |
return false; | |
size_t len = strlen(s); | |
if (len > 0) { | |
int result = 0; | |
bool negative = false; | |
int limit = -INT_MAX; | |
int index = 0; | |
char firstChar = s[0]; | |
if (firstChar < '0') { // Possible leading "+" or "-" | |
if (firstChar == '-') { | |
negative = true; | |
limit = INT_MIN; | |
} else if (firstChar != '+') | |
return false; | |
if (len == 1) // Cannot have lone "+" or "-" | |
return false; | |
index++; | |
} | |
int multmin = limit / radix; | |
while (index < len) { | |
// Accumulating negatively avoids surprises near MAX_VALUE | |
int digit = digitVal(s[index++], radix); | |
if (digit < 0) | |
return false; | |
if (result < multmin) | |
return false; | |
result *= radix; | |
if (result < limit + digit) | |
return false; | |
result -= digit; | |
} | |
*resultPtr = negative ? result : -result; | |
return true; | |
} | |
return false; | |
} | |
bool tryParseInt(const char *s, int *resultPtr) { | |
return tryParseInt(s, 10, resultPtr); | |
} | |
int parseInt(const char *s, int radix) { | |
int i; | |
return tryParseInt(s, radix, &i) ? i : 0; | |
} | |
int parseInt(const char *s) { | |
int i; | |
return tryParseInt(s, &i) ? i : 0; | |
} |
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
#pragma once | |
bool tryParseInt(const char *s, int radix, int *resultPtr); | |
bool tryParseInt(const char *s, int *resultPtr); | |
int parseInt(const char *s, int radix); | |
int parseInt(const char *s); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment