"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 depends upon the given [[base|radix]]: - For base 10, the accepted syntax 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. That is, an optional sign character, followed be a string of decimal digits, followed by an optional SI magnitude: `k`, `M`, `G`, `T`, or `P`. - For other bases, the accepted syntax is an optional sign character, followed by a string of digits of the given base. 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`. Integer: Base10 | BaseN Base10: Sign? Base10Digits Magnitude BaseN: Sign? BaseNDigits Sign: '+' | '-' Magnitude: 'k' | 'M' | 'G' | 'T' | 'P' Base10Digits: ('0'..'9')+ BaseNDigits: ('0'..'9'|'a'..'z'|'A'..'Z')+" throws (`class AssertionError`, "if [[radix]] is not between [[minRadix]] and [[maxRadix]]") see (`function Integer.parse`) tagged("Numbers", "Basic types") deprecated("Use [[Integer.parse]]") shared Integer? parseInteger( "The string representation to parse." String string, "The base, between [[minRadix]] and [[maxRadix]] inclusive." Integer radix = 10) => if (is Integer result = parseIntegerInternal(string, radix)) then result else null; Integer minRadix = 2; Integer maxRadix = 36; Integer|ParseException parseIntegerInternal( String string, Integer radix = 10) { "illegal radix" 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 ParseException("illegal format for Integer: no digits"); } value limit = negative then runtime.minIntegerValue else -runtime.maxIntegerValue; value length = string.size; variable value result = 0; variable value digitIndex = 0; variable value index = start; while (index < length) { assert (exists ch = string.getFromFirst(index)); if (index + 1 == length && radix == 10 && ch in "kMGTP") { // The SI-style magnitude "unrecognized SI magnitude" assert (exists exp = parseIntegerExponent(ch)); Integer magnitude = 10^exp; if ((limit / magnitude) < result) { result *= magnitude; break; } else { // overflow return ParseException("numeric value is too large for Integer"); } } else if (exists digit = parseDigit(ch, radix)) { // A regular digit if (result < max) { // overflow return ParseException("numeric value too large for Integer"); } result *= radix; if (result < limit + digit) { // overflow return ParseException("numeric value too large for Integer"); } // += would be much more obvious, but it doesn't work for minIntegerValue result -= digit; } else { // Invalid character return ParseException("illegal format for Integer: unexpected character '``ch``'"); } index++; digitIndex++; } if (digitIndex == 0) { return ParseException("illegal format for Integer: no digits"); } 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; }