2

I have been searching for an answer of this , but no luck

I am trying to find out a solution to perform the below operation with accuracy of 20 decimal points in PHP

9999999999999999999999999^0.2222

In built functions/GMP/BC Math does not help to do this. In built functions simply fail as the size is limited. GMP and BC math does not accept decimal exponents.

I could figure out some algorithms in stackoverflow which explains how to do this, but limited to the accuracy of the integer part alone.

I even feel that this is impossible with PHP unless we come up with an algorithm to crack this

AVC
  • 67
  • 9
  • have you tried `pow($num, 20)` or I just missed understood you!? – mamdouh alramadan Sep 30 '13 at 12:50
  • 4
    [Floating point precision is never absolute](http://php.net/manual/en/language.types.float.php), in no language, not PHP, not JS, not C... no binary system can _truly_ work with floats – Elias Van Ootegem Sep 30 '13 at 12:51
  • 1
    @mamdouh alramadan, pow($num,20) fail when value of $num exceeds a limit, say when $num gets 15 digits or above – AVC Sep 30 '13 at 12:56
  • Is your number `0.2222` accurate to 20 decimal places? Or is it really `2/9` which would be `0.22222222222...`. There are "long hand" methods for computing anything - even a thing like this. The answer will have to be represented by something other than a `double` floating point number, though. – Floris Sep 30 '13 at 12:56
  • Interesting. I didn't know that :D – mamdouh alramadan Sep 30 '13 at 12:58
  • @Sean Cheshire, its not a duplicate. There is no solution existing for this problem – AVC Sep 30 '13 at 13:11
  • @Floris, I just took an example. Basically these values can change and the solution should be capable of handling any large decimal numbers also – AVC Sep 30 '13 at 13:12

2 Answers2

2

I think I have an approach. It hinges on three simple observations:

  1. BCMath library contains a sqrt function
  2. You can break pow(x, a) into pow(x, int(a)) * fracpow(x, frac(a)) where pow exists in the BCMath library, and fracpow is a function we need to create (for an exponent a between 0 and 1)
  3. A factional power can be expressed as the product of a number of square roots:

    x^(0.22) = x^(1/8 + 1/16 + 1/32 + ...) = sqrt(sqrt(sqrt(x)))) * sqrt(sqrt(sqrt(sqrt(x)))) * ...

In other words - the approach to take is the following:

  1. Find the fractional part of the exponent
  2. Express that in powers of 2 (binary representation, basically)
  3. Keep taking the square root of your number
  4. Multiply your result by the new square root every time your factor should be included

This is not a fast method, and I suspect you need quite a few more digits of precision in the intermediate stages in order to ensure sufficient accuracy in the final result. But it will work...

If you need help implementing this let me know - I may have time later (or one of the other people looking at this answer may be inspired to write the code).

Floris
  • 45,857
  • 6
  • 70
  • 122
  • Thx. I am trying to implement the same as per your logic. So far I was trying to use log and exp together for the same. I will also check if there is a more optimized way for the second part fracpow(x, frac(a)) instead of multiple square roots – AVC Sep 30 '13 at 13:45
  • Glad my input helped. If you get your code working it would be cool to see it - perhaps you can post a link in the comments. Or you can post a new question: "this works, how do I optimize it"? That would be fun. Good luck. – Floris Sep 30 '13 at 13:53
0

You can use wolframalpha to calculate impossible math problem.

    <?php
        function pow_a($a,$b){
        $a = file_get_contents("http://www.wolframalpha.com/input/?i=$a"."%5E"."$b");
        if(preg_match_all('/first\sbtn\"\>\<a\shref\=\"(.*?)\"/', $a, $m))
            $b = file_get_contents("http://www.wolframalpha.com/input/".htmlspecialchars_decode($m[1][0]));
            if(preg_match_all("/\"stringified\"\:\s\"(.*?)\.\.\./i", $b, $k))
                return $k[1][0];
        }
        echo pow_a("9999999999999999999999999", "0.2222");
    ?>

Have a nice day

Dalım Çepiç
  • 515
  • 2
  • 12