Ejemplo n.º 1
0
 function bdiv($x, $y)
 {
     global $bs;
     global $bx2;
     global $bm;
     global $bx;
     global $bd;
     global $bdm;
     $n = count($x) - 1;
     $t = count($y) - 1;
     $nmt = $n - $t;
     if ($n < $t || $n == $t && ($x[$n] < $y[$n] || $n > 0 && $x[$n] == $y[$n] && $x[$n - 1] < $y[$n - 1])) {
         $this->q = array(0);
         $this->mod = array($x);
         return;
     }
     if ($n == $t && toppart($x, $t, 2) / toppart($y, $t, 2) < 4) {
         $qq = 0;
         $xx = 0;
         for (;;) {
             $xx = bsub($x, $y);
             if (count($xx) == 0) {
                 break;
             }
             $x = $xx;
             $qq++;
         }
         $this->q = array($qq);
         $this->mod = $x;
         return;
     }
     $shift2 = floor(log($y[$t]) / M_LN2) + 1;
     $shift = $bs - $shift2;
     if ($shift) {
         $x = array_merge((array) $x);
         $y = array_merge((array) $y);
         for ($i = $t; $i > 0; $i--) {
             $y[$i] = $y[$i] << $shift & $bm | $y[$i - 1] >> $shift2;
         }
         $y[0] = $y[0] << $shift & $bm;
         if ($x[$n] & ($bm << $shift2 & $bm)) {
             $x[++$n] = 0;
             $nmt++;
         }
         for ($i = $n; $i > 0; $i--) {
             $x[$i] = $x[$i] << $shift & $bm | $x[$i - 1] >> $shift2;
         }
         $x[0] = $x[0] << $shift & $bm;
     }
     $i = 0;
     $j = 0;
     $x2 = 0;
     $q = zeros($nmt + 1);
     $y2 = array_merge(zeros($nmt), (array) $y);
     for (;;) {
         $x2 = bsub($x, $y2);
         if (count($x2) == 0) {
             break;
         }
         $q[$nmt]++;
         $x = $x2;
     }
     $yt = $y[$t];
     $top = toppart($y, $t, 2);
     for ($i = $n; $i > $t; $i--) {
         $m = $i - $t - 1;
         if ($i >= count($x)) {
             $q[$m] = 1;
         } else {
             if ($x[$i] == $yt) {
                 $q[$m] = $bm;
             } else {
                 $q[$m] = floor(toppart($x, $i, 2) / $yt);
             }
         }
         $topx = toppart($x, $i, 3);
         while ($q[$m] * $top > $topx) {
             $q[$m]--;
         }
         $y2 = array_slice($y2, 1);
         $x2 = bsub($x, bmul(array($q[$m]), $y2));
         if (count($x2) == 0) {
             $q[$m]--;
             $x2 = bsub($x, bmul(array($q[m]), $y2));
         }
         $x = $x2;
     }
     if ($shift) {
         for ($i = 0; $i < count($x) - 1; $i++) {
             $x[$i] = $x[$i] >> $shift | $x[$i + 1] << $shift2 & $bm;
         }
         $x[count($x) - 1] >>= $shift;
     }
     $n = count($q);
     while ($n > 1 && $q[$n - 1] == 0) {
         $n--;
     }
     $this->q = array_slice($q, 0, $n);
     $n = count($x);
     while ($n > 1 && $x[$n - 1] == 0) {
         $n--;
     }
     $this->mod = array_slice($x, 0, $n);
 }
Ejemplo n.º 2
0
/**
 * @param $x
 * @param $m
 * @param $mu
 * @return array
 */
function bmod2($x, $m, $mu)
{
    $xl = count($x) - (count($m) << 1);
    if ($xl > 0) {
        return bmod2(array_concat(array_slice($x, 0, $xl), bmod2(array_slice($x, $xl), $m, $mu)), $m, $mu);
    }
    $ml1 = count($m) + 1;
    $ml2 = count($m) - 1;
    $q3 = array_slice(bmul(array_slice($x, $ml2), $mu), $ml1);
    $r1 = array_slice($x, 0, $ml1);
    $r2 = array_slice(bmul($q3, $m), 0, $ml1);
    $r = bsub($r1, $r2);
    if (count($r) == 0) {
        $r1[$ml1] = 1;
        $r = bsub($r1, $r2);
    }
    for ($n = 0;; $n++) {
        $rr = bsub($r, $m);
        if (count($rr) == 0) {
            break;
        }
        $r = $rr;
        if ($n >= 3) {
            return bmod2($r, $m, $mu);
        }
    }
    return $r;
}