Search code examples
phpnumbersradix

How to define a custom base of numbers in php?


I need to define new number base for my custom calculations,

I have an order list of 11 chars (lets say a,h,k,d,e,f,g,z,i,j,m) I want to to be able to perform mathematics tasks on them like they were a number base. For example a+h=k, a+k=d, j++=m and etc...

Is this possible?

The best way I thought of is taking regular base of 11 and just replace all chars before and after the calculation it self (so j++ would be actually 9++=a and then a will be translated into m). This way is not very efficient but will work.

Any better ideas?

Thank you.


Solution

  • PHP offers to perform math operations for decimal, octal, hexadecimal and binary numbers natively. If you want to do calculations with other kinds of number systems you need to convert them to one of the above kinds.

    Basically you are using a base11 number system - having custom digits. PHP offers the function base_convert() to convert numbers between systems with a different base. Having this, you just need to translate your custom digits to base11 then base11 to decimal then calculate and then convert it back.

    Hackish!, but it can be done like this.

    function add($a, $b) {
        $custom_digits = 'ahkdefgzijm';
        $base11_digits = '0123456789A';
    
        // translate custom numbers to base11
        $base11_a = strtr($a, $custom_digits, $base11_digits);
        $base11_b = strtr($a, $custom_digits, $base11_digits);
    
        // translate base11 numbers to decimal
        $decimal_a = base_convert($base11_a, 11, 10);
        $decimal_b = base_convert($base11_b, 11, 10);
    
        // Do the calculation
        $result = $decimal_a + $decimal_b;
    
        // Convert result back to base11
        $base11_result = base_convert($result, 10, 11);
    
        // Translate base11 result into customer digits
        return strtr($base11_result, $base11_digits, $custom_digits);
    }
    

    And never forget!:

    h + h == k
    

    :)


    A more flexible attempt could be to create two functions like this:

    function dec_to_custom($n) {
        static $custom_digits = 'ahkdefgzijm';
        static $base11_digits = '0123456789a';
        return strtr(base_convert($n, 10, 11), $base11_digits, $custom_digits);
    }
    
    function custom_to_dec($n) {
        static $custom_digits = 'ahkdefgzijm';
        static $base11_digits = '0123456789a';
        $base11 = strtr($n, $custom_digits, $base11_digits);
        return base_convert($base11, 11, 10);
    }
    

    And the use them like you wish in (integer!) math operations:

    echo dec_to_custom(custom_to_dec(1) + custom_to_dec(1));
    

    Update

    Looks like I answered too fast. You had already a solution like I suggested and you are concerned about the strtr() usage. I can only say that I did a similar task once and did a lot of profiling and ended up using strtr() since it showed the best performance.