views:

936

answers:

3

What is the best way to convert decimal numbers (base ten) to sexagesimal (base sixty) represented as a string using 0-9, A-Z and a-x as the digits.

I'm planning to code it in javascript but any help is appreciated.

Usage Example:

>>decToSex(60);
"10"
>>decToSex(123);
"23"
>>decToSex(1000000);
"4bke"
>>decToSex(1234567.89);
"5gu7.rO"

The final code I used, based on Paolo's answer:

var decToSex = function(){
    var decToSexMap = ['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','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x'];

    return function(number){

     var negative = '';
     if (number < 0){
      var negative = '-';
     }

     number = number.toString().split('.');
     var integer = Math.abs(number[0]);
     var fraction = number[1];
     var result = '';

     do {
      result = decToSexMap[integer % 60] + result;
      integer = parseInt(integer / 60);
     } while (integer > 0);

     if (fraction){
      var decimalPlaces = fraction.toString().length;
      result += '.';
      fraction = parseFloat('.' + fraction);

      var x = 0;
      do {
       x++;
       var res = (fraction * 60).toString().split('.');
       result = result + decToSexMap[res[0]];

       if (res[1]) {
        fraction = parseFloat('.' + res[1]);
       }
       else {
        break;
       }
      } while (x < decimalPlaces);
     }
     return negative + result;
    }
}();
A: 

Just repeatedly divide it by 60 until you're left with zero. Each time, grab the modulus, and convert that into the appropriate character, and add it to your output string.

Edit: For decimals, say you're searching up to 3 60decimal places:

Start with 0.98765 (base 10)

0.98765 * 60 -> 59.259 -> first post-decimal character is 59 converted to its 60decimal character, then carry the .259
.259 * 60 -> 15.54 -> second char is 15 converted to its 60decimal character, then carry the .54
.54 * 60 -> 32.4 -> round it this time (its the last char) -> last char is 32 as its 60dec char

So 0.98765 (base 10) becomes 0.[59] [15] [32] (base 60)

Chris
How would that work with fractions: 1234567.89 -> "5gu7.rO" ?
Annan
You'd need to first specify how many decimal places you want it evaluated to, and then work from there.
Chris
Try my edit above on a scrap of paper...
Chris
+1  A: 

This works with the test data provided, but you probably wanna run a few more tests on it:

<script>
var convert = new Array(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',
                       'b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q',
                       'r','s','t','u','v','w','x');

function decToSex(num) {
    var extract = num.toString().split('.');
    num = extract[0];
    var pieces = new Array();
    do {
        pieces.push(convert[num % 60]);
        num = parseInt(num/60);
    } while (num > 0);
    pieces = pieces.reverse();
    var rem = extract[1];
    if(rem) {
        rem = parseFloat('.' + rem);
        var x = 0;
        var dec = new Array();
        do {
            x++;
            var res = (rem * 60).toString().split('.');
            dec.push(convert[res[0]]);
            if(res[1]) {
                rem = parseFloat('.' + res[1]);
            } else {
                break;
            }
        } while (x < 3); // work up to 3 decimal places, change for more.
    }
    var myResult = pieces.join('');
    if(dec) {
        myResult += '.' + dec.join('');
    }
    return myResult;
}

alert(decToSex(60));
alert(decToSex(123));
alert(decToSex(1000000));
alert(decToSex(1234567.89));
</script>
Paolo Bergantino
A: 

Start by splitting the number into an integer and fractional part.

For the integer part, take the modulus to pull of the least-significant digit, then divide by 60 and repeat.

For the fractional part, repeatedly multiply by 60 and take the integer part to get the result digits. If you ever end up with zero, which is unlikely, you are finished. More likely you will want to terminate after you extract a certain number of digits.

David Norman