andy-h
2/5/2014 - 4:18 PM

Convert a number to a different base (e.g., from hex to decimal)

Convert a number to a different base (e.g., from hex to decimal)

//Convert a number to a different base (e.g., from hex to decimal)
//converts floating point numbers as well as integers
//returns NaN if `num` is not a number of the specified base (the entire string must be valid, not just the beginning like how parseInt() does it)

function changeBase(num, fromRadix, toRadix){
	var rxp, letters, m, whole, part;
	
	if(fromRadix%1 !== 0 || fromRadix < 2 || fromRadix > 36 || toRadix%1 !== 0 || toRadix < 2 || toRadix > 36){
		throw (new RangeError("Illegal radix. Radices must be integers between 2 and 36, inclusive."));
	}
	
	//convert radices to number primitives (for speed)
	fromRadix = 1*fromRadix;
	toRadix = 1*toRadix;
	
	//construct a regular expression pattern, based on the current radix, to extract the whole part and the remainer
	if(fromRadix <= 10){
		rxp = "^([0-"+(fromRadix-1)+"]*)(?:\\.([0-"+(fromRadix-1)+"]*))?$";
	}
	else if(fromRadix === 11){
		rxp = "^([0-9A]*)(?:\\.([0-9A]*))?$";
	}
	else{
		letters = "BCDEFGHIJKLMNOPQRSTUVWXYZ";
		rxp = "^([0-9A-"+letters[fromRadix-12]+"]*)(?:\\.([0-9A-"+letters[fromRadix-12]+"]*))?$";
	}
	
	//get strings containing the whole part and the remainder
	m = (new RegExp(rxp, "i")).exec(num);
	if(!m) return 0/0;	///`num` is not a number of the specified base; return NaN
	
	whole = m[1] || "0";
	part = m[2] || "0";
	
	//convert the number to decimal
	whole = parseInt(whole, fromRadix);
	part = parseInt(part, fromRadix) / Math.pow(fromRadix, part.length);
	num = whole+part;
	
	//convert the decimal number to desired base
	num = num.toString(toRadix);
	
	return num.toUpperCase();
}