BaseConversion (v2)

Revision 2 of this benchmark created by Alexander Lamannis on


Description

Converts from any base to another. Returns false on errors (bases < 2, or unexpected error). Returns the new number as a string. The test uses a simple rng to decide which number and bases (probably results in incorrect number-base pairings) to use per test iteration.

I decided to compare the performance to that of parseInt. It's easy to see that parseInt is MUCH faster, but it only converts to base 10 from another base between 2 and 36, other wise it just returns NaN. Mine can handle many more cases correctly which I see as worth the performance hit.

Current syntax => base(numtoconvert,currentbase,targetbase) All parameters are currently required.

Preparation HTML

<script type="text/javascript">
  function rand(lo, hi) {
    return Math.floor(Math.random() * (hi - lo + 1) + lo);
  }
</script>

Setup

function base(iNum, iBase, fBase) {
    if (fBase < 2) return false;
  
    function flip(arr) {
      var x = arr.length,
          narr = [];
      while (x--) {
        narr.push(arr[x]);
      }
      return narr;
    }
    var i = 0,
        rem, digit = [],
        fNum = [];
    var alphaNum = {
      alphas: [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'],
      a: 10,
      b: 11,
      c: 12,
      d: 13,
      e: 14,
      f: 15,
      g: 16,
      h: 17,
      i: 18,
      j: 19,
      k: 20,
      l: 21,
      m: 22,
      n: 23,
      o: 24,
      p: 25,
      q: 26,
      r: 27,
      s: 28,
      t: 29,
      u: 30,
      v: 31,
      w: 32,
      x: 33,
      y: 34,
      z: 35
    };
    //for ease of calculations, convert current num to _10 first if not already _10
    if (iBase !== 10 || fBase === 10) {
      var tNum = iNum.toString().split(''),
          k = tNum.length,
          pows = [],
          temp = [];
      while (k--) {
        pows[k] = Math.pow(iBase, k);
      }
      pows = flip(pows);
      k = tNum.length;
      //if the incoming number has letters, they need to be converted to appropriate ints
      var u = alphaNum['alphas'].length,
          h = 0,
          reg;
      for (i; i < k; i++) {
        if (/[a-zA-Z]/.test(tNum[i]) && Object.prototype.toString.call(tNum[i]) === '[object String]') {
          tNum[i] = alphaNum[tNum[i].toLowerCase()];
        }
      }
      i = 0;
      for (i; i < k; i++) {
        temp.push(tNum[i] * pows[i]);
      }
      var fDigit = 0;
      i = 0;
      for (i; i < k; i++) {
        fDigit += temp[i];
      }
      if (fBase === 10) {
        return fDigit;
      }
    }
    if (fDigit) {
      iNum = fDigit;
    }
    i = 0;
    while (iNum !== 0) {
      rem = iNum % fBase;
      iNum = Math.floor(iNum / fBase);
      fNum[i] = rem;
      i++;
    }
    if (fNum) {
      if (fBase > 10 && fBase < 37) {
        //flip(fNum);
        var q = 0,
            w = fNum.length;
        for (q; q < w; q++) {
          if (fNum[q] > 9 && fNum[q] < 37) {
            fNum[q] = alphaNum['alphas'][fNum[q]];
          }
        }
        return flip(fNum).join('');
      } else if (fBase > 37) return flip(fNum).join(':');
      return flip(fNum).join('');
    }
    return false;
  }

  Benchmark.prototype.setup = function() {
    var iNum_1 = rand(0, 100);
    var iBase_1 = rand(2, 100);
    var fBase_1 = rand(2, 100);
    
    var iNum_2 = rand(500, 1e+3);
    var iBase_2 = rand(2, 250);
    var fBase_2 = rand(100, 250);
    
    var iNum_3 = rand(1e+3, 1e+6);
    var iBase_3 = rand(2, 500);
    var fBase_3 = rand(250, 500);
    
    var iNum_4 = rand(0, 100).toString();
    var fBase_4 = rand(2, 100);
    
    var iNum_5 = rand(500, 1e+3).toString();
    var fBase_5 = rand(100, 250);
    
    var iNum_6 = rand(1e+3, 1e+6).toString();
    var fBase_6 = rand(250, 500);
  };

Test runner

Ready to run.

Testing in
TestOps/sec
Smaller Nums
base(iNum_1, iBase_1, fBase_1);
ready
Medium Nums
base(iNum_2, iBase_2, fBase_2);
ready
Larger Nums
base(iNum_3, iBase_3, fBase_3);
ready
parseInt Small Nums
parseInt(iNum_4, fBase_4);
ready
parseInt Medium Nums
parseInt(iNum_5, fBase_5);
ready
parseInt Larger Nums
parseInt(iNum_6, fBase_6);
ready

Revisions

You can edit these tests or add more tests to this page by appending /edit to the URL.

  • Revision 2: published by Alexander Lamannis on