2012-06-28 28 views
5

Chúng tôi đang tìm kiếm thư mục gốc thứ N trong PHP. Chúng tôi cần phải làm điều này với một số lượng rất lớn, và các cửa sổ máy tính trả về 2. Với mã sau đây chúng tôi đang nhận được 1. Không ai có một ý tưởng làm thế nào điều này hoạt động?Tính toán gốc thứ N bằng bcmath trong PHP

echo bcpow(18446744073709551616, 1/64); 
+2

Không hoạt động, bởi vì bcpow() chỉ chấp nhận số nguyên. Nếu gốc thứ 64 là tất cả những gì bạn cần, thay vào đó hãy làm sáu rễ vuông. – Niko

Trả lời

10

Vâng có vẻ như PHP và lib BC có một số giới hạn, và sau khi tìm kiếm trên internet tôi tìm thấy này interesting article/code:

Vì vậy, bạn nên sử dụng chức năng này:

<?php 

function NRoot($num, $n) { 
    if ($n<1) return 0; // we want positive exponents 
    if ($num<=0) return 0; // we want positive numbers 
    if ($num<2) return 1; // n-th root of 1 or 2 give 1 

    // g is our guess number 
    $g=2; 

    // while (g^n < num) g=g*2 
    while (bccomp(bcpow($g,$n),$num)==-1) { 
     $g=bcmul($g,"2"); 
    } 
    // if (g^n==num) num is a power of 2, we're lucky, end of job 
    if (bccomp(bcpow($g,$n),$num)==0) { 
     return $g; 
    } 

    // if we're here num wasn't a power of 2 :( 
    $og=$g; // og means original guess and here is our upper bound 
    $g=bcdiv($g,"2"); // g is set to be our lower bound 
    $step=bcdiv(bcsub($og,$g),"2"); // step is the half of upper bound - lower bound 
    $g=bcadd($g,$step); // we start at lower bound + step , basically in the middle of our interval 

    // while step!=1 

    while (bccomp($step,"1")==1) { 
     $guess=bcpow($g,$n); 
     $step=bcdiv($step,"2"); 
     $comp=bccomp($guess,$num); // compare our guess with real number 
     if ($comp==-1) { // if guess is lower we add the new step 
      $g=bcadd($g,$step); 
     } else if ($comp==1) { // if guess is higher we sub the new step 
      $g=bcsub($g,$step); 
     } else { // if guess is exactly the num we're done, we return the value 
      return $g; 
     } 
    } 

    // whatever happened, g is the closest guess we can make so return it 
    return $g; 
} 

echo NRoot("18446744073709551616","64"); 

?> 

Hy vọng điều này hữu ích ...

+2

Cảm ơn! Làm việc như một say mê! Tôi sẽ cung cấp cho bạn một +10 nhưng tôi chỉ có thể làm +1: P –

Các vấn đề liên quan