Convert numbers from base X to base Y
Bug

I tried converting "10' from base 10 to base 2 (i.e. binary) and the output was 250, which is invalid for a base 2 number.

Also, when I ran convertBase("3", 10, 3) the output was 0, not "10"

Your Question


  am I using modern coding conventions/practices?


Originally, before I added the javascript tag, this question only had the ecmascript-6 tag. I don't see many features of es-6 in your code, like let and const, arrow functions, default parameters, etc. So judging from an ecmascript-6 point-of-view, I would say No. See the rewrite below which utilizes those features.



const convertBase = (inNumber, inBase = 10, outputBase = 10) =&gt; {
  let result = [];
  if (typeof inNumber !== "number" &amp;&amp; typeof inNumber !== "string") {
    throw new Error("You input is not a number or a string.");
  }
  const encodings = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"];
  if (typeof inNumber === "number") {
    inNumber = JSON.stringify(inNumber);
  }
  if (inBase === outputBase) {
    return inNumber;
  }
  inNumber = inNumber.toLowerCase();
  inNumber = inNumber.split("").map(item =&gt; encodings.indexOf(item));
  inNumber = inNumber.reverse();
  inNumber = inNumber.map((item, index)  =&gt; item * Math.pow(inBase, index));
  let res = 0;
  inNumber.forEach(item =&gt; res += item);
  let ones = res % outputBase;
  let remainder = (res - res % outputBase) / outputBase;
  result.unshift(ones);
  let left = remainder &gt; 1;
  while (left) {
    ones = remainder;
    remainder = (remainder - remainder % outputBase) / outputBase;
    result.unshift(ones);
    left = remainder &gt; 1;
  }
  return result.map(item =&gt; encodings[item]).join("");
};
console.log('convertBase("10", 10, 11):',convertBase("10", 10, 11))




Re-declarations

The code inside the while loop contains variable declarations for variables declared outside the loop:


var ones = res % outputBase;
var remainder = (res - res % outputBase) / outputBase;
result.unshift(ones);
var left = remainder &gt; 1;
while (left) {
  var ones = remainder;
  var remainder = (remainder - remainder % outputBase) / outputBase;
  result.unshift(ones);
  var left = remainder &gt; 1;
}



While the Javascript engine won't "chuck a wobbly1"2 (though somebody who has to update your code might), those assignment statements inside the while loop could exist without the var keyword, and for the sake of readability, probably should not have var at the beginning.

Simplification

The first versions of Ecmascript (i.e. 1 and 5) have had parseInt() and Number.prototype.toString(), which should be enough to implement the desired functionality (though note that the supported base values are 2-36, not 0-26).



const convertBase = (inputNumber, inputBase = 10, outputBase = 10) =&gt;
  parseInt(inputNumber, inputBase).toString(outputBase);

console.log('convertBase("10", 10, 11):', convertBase("10", 10, 11)); // "a"
console.log('convertBase("3", 10, 3):', convertBase("3", 10, 3)); // "10"
console.log('convertBase("4", 10, 3):', convertBase("4", 10, 3)); // "11"
console.log('convertBase(10, 10, 2):', convertBase(10, 10, 2)); // "1010"




1http://spencertipping.com/js-in-ten-minutes/js-in-ten-minutes.pdf
2https://english.stackexchange.com/a/129277/213844