Integer minRadix = 2; Integer maxRadix = 36; "The [[Integer]] value of the given [[string representation|string]] of an integer value in the base given by [[radix]], or `null` if the string does not represent an integer in that base, or if the mathematical integer it represents is too large in magnitude to be represented by an instance of the class `Integer`. The syntax accepted by this function is the same as the syntax for an `Integer` literal in the Ceylon language except that it may optionally begin with a sign character (`+` or `-`) and may not contain grouping underscore characters. The given `radix` specifies the base of the string representation. The list of available digits starts from `0` to `9`, followed by `a` to `z`. When parsing in a specific base, the first `radix` digits from the available digits list is used. This function is not case sensitive; `a` and `A` both correspond to the digit `a` whose decimal value is `10`." throws (`class AssertionError`, "if [[radix]] is not between [[minRadix]] and [[maxRadix]]") see (`function formatInteger`, `function parseFloat`) tagged("Numbers", "Basic types") shared Integer? parseInteger( "The string representation to parse." String string, "The base, between [[minRadix]] and [[maxRadix]] inclusive." Integer radix = 10) { assert (minRadix <= radix <= maxRadix); Integer start; Integer max = runtime.minIntegerValue / radix; // Parse the sign Boolean negative; if (exists char = string.first) { if (char == '-') { negative = true; start = 1; } else if (char == '+') { negative = false; start = 1; } else { negative = false; start = 0; } } else { return null; } Integer limit = negative then runtime.minIntegerValue else -runtime.maxIntegerValue; Integer length = string.size; variable Integer result = 0; variable Integer digitIndex = 0; variable Integer index = start; while (index < length) { assert (exists ch = string.getFromFirst(index)); if (index + 1 == length && radix == 10 && ch in "kMGTP") { // The SI-style magnitude if (exists exp = parseIntegerExponent(ch)) { Integer magnitude = 10^exp; if ((limit / magnitude) < result) { result *= magnitude; break; } else { // overflow return null; } } else { return null; } } else if (exists digit = parseDigit(ch, radix)) { // A regular digit if (result < max) { // overflow return null; } result *= radix; if (result < limit + digit) { // overflow return null; } // += would be much more obvious, but it doesn't work for minIntegerValue result -= digit; } else { // Invalid character return null; } index++; digitIndex++; } if (digitIndex == 0) { return null; } else { return negative then result else -result; } } Integer? parseIntegerExponent(Character char) { switch (char) case ('P') { return 15; } case ('T') { return 12; } case ('G') { return 9; } case ('M') { return 6; } case ('k') { return 3; } else { return null; } } Integer aIntLower = 'a'.integer; Integer aIntUpper = 'A'.integer; Integer zeroInt = '0'.integer; Integer? parseDigit(Character digit, Integer radix) { Integer figure; Integer digitInt = digit.integer; if (0<=digitInt-zeroInt<10) { figure=digitInt-zeroInt; } else if (0<=digitInt-aIntLower<26) { figure=digitInt-aIntLower+10; } else if (0<=digitInt-aIntUpper<26) { figure=digitInt-aIntUpper+10; } else { return null; } return figure<radix then figure; }