public class Numeral { /** "string to int" -- same as Integer.parseInt(String,int). * @param numeral the base-b numeral to convert into a (non-negative) number. * Digits only -- no sign allowed. * @param base The base of the numeral (base >= 2). * @return The int corresponding to `numeral`. The empty numeral is 0. */ public static int stoi( String numeral, short base ) { int numSoFar = 0; int columnWeight = 1; // Start at 1's column, then 10s,100s,... (if base==10) for (int i=0; i < numeral.length(); ++i ) { numSoFar += dtoi( numeral.charAt( numeral.length()-1-i ) ) * columnWeight; columnWeight *= base; // Alternately, Horner's algorithm: // numSoFar = numSoFar * base + dtoi( numeral.charAt( i ) ); } return numSoFar; } /** "string to int" -- same as Integer.parseInt(String). * @param numeral the base-10 numeral to convert into a (non-negative) number. * Digits only -- no sign allowed. * @return The int corresponding to `numeral`. The empty numeral is 0. */ public static int stoi( String numeral ) { return Numeral.stoi(numeral,(short)10); } /** "int to string" -- same as Integer.toString(int,int). * @param n the non-negative int to convert into a numeral (String). * @param base The base of the numeral (base >= 2). * @return The numeral (String) corresponding to `n`, written base `base`. */ public static String itos( int n, short base ) { String numeralSoFar = ""; int num = n; while (num > 0) { numeralSoFar = itod((short)(num % base)) + numeralSoFar; num = num / base; } return numeralSoFar.equals("") ? "0" : numeralSoFar; } /** "int to string" -- same as Integer.toString(int,int). * @param n the non-negative int to convert into a numeral (String). * @return The numeral (String) corresponding to `n`, written base `base`. */ public static String itos( int n ) { return Numeral.itos(n,(short)10); } /** "digit to int": Convert a digit to an int. * @param d a digit in '0'..'9' or (for hex digits) in 'A'..'F' or 'a'..'f'. * @return the value of the digit 'd'. */ static int dtoi( char d ) { if (d < '0') { throw new IllegalArgumentException("Bad digit passed to dtoi: '" + d + "'"); } else if ('0' <= d && d <= '9') { return (int)(d-'0'); } else if ('A' <= d && d <= 'a') { return 10+(int)(d-'A'); } else if ('a' <= d && d <= 'z') { return 10+(int)(d-'a'); } else { // d is beyond 'z'. throw new IllegalArgumentException("Bad digit passed to dtoi: '" + d + "'"); } } /** "int to digit": Convert an int to a single digit. * @param n A number in [0,16). * @return a char in '0'..'9','A'..'F'. */ static char itod( short n ) { if (n < 0) { throw new IllegalArgumentException("itod: digit can't be negative: " + n); } else if (n >= MAX_DIGIT) { throw new IllegalArgumentException("itod: digit >= "+ MAX_DIGIT+": " + n); } else if (n < 10) { return (char)(((short)'0')+n); } else { return (char)(((short)'A')+(n-10)); } } static final short MAX_DIGIT = ((short)'a')-((short)'A')+10; // After 0..9 we go A,B,C..., and even into puctuation beyond 'Z', // but if we go further into the lower-case letters ('a' or beyond), // that's very confusing. }