Skip to content

Instantly share code, notes, and snippets.

@gamerforEA
Created December 1, 2017 11:26
Show Gist options
  • Save gamerforEA/0b0216d605345c7d8e0e6a48ae641f66 to your computer and use it in GitHub Desktop.
Save gamerforEA/0b0216d605345c7d8e0e6a48ae641f66 to your computer and use it in GitHub Desktop.
C++ integer parser (based on JVM sources)
#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;
}
#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