Skip to main content
Stack Overflow
  1. About
  2. For Teams

Return to Question

Notice removed Draw attention by Community Bot
Bounty Ended with Booboo's answer chosen by Community Bot
added 616 characters in body
Source Link
szmegma
  • 249
  • 4
  • 9
function bdiv($x,$y){
 global $bs, $bm, $bx2, $bx, $bd, $bdm, $log2;
 $arr=[];
 $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]))
 return ['q'=>[0], 'mod'=>$x];
 if($n==$t && toppart($x,$t,2)/toppart($y,$t,2) <4){
 $q=0;
 for(;;){
 $xx=bsub($x,$y);
 if(count($xx)==0)
 break;
 $x=$xx;
 $q++;
 }
 return ['q'=>[$q], 'mod'=>$x];
 }
 $shift2=floor(log($y[$t])/$log2)+1;
 $shift=$bs-$shift2;
 if($shift){
/////////////////////////////////////////////// Kiran Shakya solutionBooboo
 //$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;
 }
 $q=zeros($nmt+1);
 //array_push($arr, zeros($nmt));
 //array_push($arr, $y);
 //$y2=array_merge(...$arr);
 //////////////////////////////////// use array_merge straight away
 $y2=array_merge(zeros($nmt),$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([$q[$m]],$y2));
 if(count($x2)==0){
 $q[$m]--;
 $x2=bsub($x,bmul([$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;
 }
 while(count($q) > 1 && $q[count($q)-1]==0)
 $q=array_slice($q, 0, count($q)-1);
 while(count($x) > 1 && $x[count($x)-1]==0)
 $x=array_slice($x, 0, count($x)-1);
 return ['q'=>$q, 'mod'=>$x];
}

==========================> UPDATE I

==========================> UPDATE II

I applied Booboo solution, I just completely skipped the concat() parts

So the inputs are:

$x=[ 210763776, 109357119, 261308872];
$start=2;
$len=2;
$bx2=268435456;

...and returns 70144566321522751 in PHP and 70144566321522750 in JS. I use bcadd() and bcmul() but the result is same if I'm using math operator signs.

function toppart($x,$start,$len){
 global $bs, $bm, $bx2, $bx, $bd, $bdm, $log2;
 $n=0;
 while($start >= 0 && $len > 0){
 $n= bcadd(bcmul($n, $bx2),$x[$start--]);
 $len--;
 }
 return $n;
}
function bdiv($x,$y){
 global $bs, $bm, $bx2, $bx, $bd, $bdm, $log2;
 $arr=[];
 $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]))
 return ['q'=>[0], 'mod'=>$x];
 if($n==$t && toppart($x,$t,2)/toppart($y,$t,2) <4){
 $q=0;
 for(;;){
 $xx=bsub($x,$y);
 if(count($xx)==0)
 break;
 $x=$xx;
 $q++;
 }
 return ['q'=>[$q], 'mod'=>$x];
 }
 $shift2=floor(log($y[$t])/$log2)+1;
 $shift=$bs-$shift2;
 if($shift){
/////////////////////////////////////////////// Kiran Shakya solution
 $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;
 }
 $q=zeros($nmt+1);
 //array_push($arr, zeros($nmt));
 //array_push($arr, $y);
 //$y2=array_merge(...$arr);
 //////////////////////////////////// use array_merge straight away
 $y2=array_merge(zeros($nmt),$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([$q[$m]],$y2));
 if(count($x2)==0){
 $q[$m]--;
 $x2=bsub($x,bmul([$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;
 }
 while(count($q) > 1 && $q[count($q)-1]==0)
 $q=array_slice($q, 0, count($q)-1);
 while(count($x) > 1 && $x[count($x)-1]==0)
 $x=array_slice($x, 0, count($x)-1);
 return ['q'=>$q, 'mod'=>$x];
}

==========================> UPDATE

function bdiv($x,$y){
 global $bs, $bm, $bx2, $bx, $bd, $bdm, $log2;
 $arr=[];
 $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]))
 return ['q'=>[0], 'mod'=>$x];
 if($n==$t && toppart($x,$t,2)/toppart($y,$t,2) <4){
 $q=0;
 for(;;){
 $xx=bsub($x,$y);
 if(count($xx)==0)
 break;
 $x=$xx;
 $q++;
 }
 return ['q'=>[$q], 'mod'=>$x];
 }
 $shift2=floor(log($y[$t])/$log2)+1;
 $shift=$bs-$shift2;
 if($shift){
/////////////////////////////////////////////// Booboo
 //$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;
 }
 $q=zeros($nmt+1);
 //array_push($arr, zeros($nmt));
 //array_push($arr, $y);
 //$y2=array_merge(...$arr);
 //////////////////////////////////// use array_merge straight away
 $y2=array_merge(zeros($nmt),$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([$q[$m]],$y2));
 if(count($x2)==0){
 $q[$m]--;
 $x2=bsub($x,bmul([$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;
 }
 while(count($q) > 1 && $q[count($q)-1]==0)
 $q=array_slice($q, 0, count($q)-1);
 while(count($x) > 1 && $x[count($x)-1]==0)
 $x=array_slice($x, 0, count($x)-1);
 return ['q'=>$q, 'mod'=>$x];
}

==========================> UPDATE I

==========================> UPDATE II

I applied Booboo solution, I just completely skipped the concat() parts

So the inputs are:

$x=[ 210763776, 109357119, 261308872];
$start=2;
$len=2;
$bx2=268435456;

...and returns 70144566321522751 in PHP and 70144566321522750 in JS. I use bcadd() and bcmul() but the result is same if I'm using math operator signs.

function toppart($x,$start,$len){
 global $bs, $bm, $bx2, $bx, $bd, $bdm, $log2;
 $n=0;
 while($start >= 0 && $len > 0){
 $n= bcadd(bcmul($n, $bx2),$x[$start--]);
 $len--;
 }
 return $n;
}
I apply Kiran Shakya solution in the code, but there is a new behaviour appeared when the PHP operated with arbitrary precision numbers in the toppart() function.
Source Link
szmegma
  • 249
  • 4
  • 9
function bdiv($x,$y){
 global $bs, $bm, $bx2, $bx, $bd, $bdm, $log2;
 $arr=[];
 $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]))
 return ['q'=>[0], 'mod'=>$x];
 if($n==$t && toppart($x,$t,2)/toppart($y,$t,2) <4){
 $q=0;
 for(;;){
 $xx=bsub($x,$y);
 if(count($xx)==0)
 break;
 $x=$xx;
 $q++;
 }
 return ['q'=>[$q], 'mod'=>$x];
 }
 $shift2=floor(log($y[$t])/$log2)+1;
 $shift=$bs-$shift2;
 if($shift){
/////////////////////////////////////////////////// the problem startKiran hereShakya withsolution
 the concat()
 $x = array_pusharray_merge($xarray(),$x);
 array_push($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;
 }
 $q=zeros($nmt+1);
 //array_push($arr, zeros($nmt));
 //array_push($arr, $y);
 //$y2=array_merge(...$arr);
 //////////////////////////////////// use array_merge straight away
 $y2=array_merge(zeros($nmt),$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([$q[$m]],$y2));
 if(count($x2)==0){
 $q[$m]--;
 $x2=bsub($x,bmul([$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;
 }
 while(count($q) > 1 && $q[count($q)-1]==0)
 $q=array_slice($q, 0, count($q)-1);
 while(count($x) > 1 && $x[count($x)-1]==0)
 $x=array_slice($x, 0, count($x)-1);
 return ['q'=>$q, 'mod'=>$x];
}

==========================> UPDATE

@Kiran Shakya idea to replace x=x.concat() with $x=array_merge(array(),$x); is actually working or at least I don't get any PHP error or warning on that, but start an infinite loop, which I have to shut manually. The script calling the toppart function, which operating with arbitrary precision numbers (multiply and add):

 function toppart(x,start,len) {
 var n=0
 while(start >= 0 && len > 0){
 n=n*bx2+x[start--]
 len--
 }
 return n
 }

The interesting part is, the JS returned for an example 70144566321522750 but the PHP returned 70144566321522751. In the later loop the differences are much bigger.
I have checked all numbers in both versions and all the same inputs: x,start,len,bx2. This can be a bug or one of them cannot handle big integers or what can be the reason?

function bdiv($x,$y){
 global $bs, $bm, $bx2, $bx, $bd, $bdm, $log2;
 $arr=[];
 $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]))
 return ['q'=>[0], 'mod'=>$x];
 if($n==$t && toppart($x,$t,2)/toppart($y,$t,2) <4){
 $q=0;
 for(;;){
 $xx=bsub($x,$y);
 if(count($xx)==0)
 break;
 $x=$xx;
 $q++;
 }
 return ['q'=>[$q], 'mod'=>$x];
 }
 $shift2=floor(log($y[$t])/$log2)+1;
 $shift=$bs-$shift2;
 if($shift){
/////////////////////////////////////////////////// the problem start here with the concat()
 array_push($x,$x);
 array_push($y,$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;
 }
 $q=zeros($nmt+1);
 array_push($arr, zeros($nmt));
 array_push($arr, $y);
 $y2=array_merge(...$arr);
 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([$q[$m]],$y2));
 if(count($x2)==0){
 $q[$m]--;
 $x2=bsub($x,bmul([$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;
 }
 while(count($q) > 1 && $q[count($q)-1]==0)
 $q=array_slice($q, 0, count($q)-1);
 while(count($x) > 1 && $x[count($x)-1]==0)
 $x=array_slice($x, 0, count($x)-1);
 return ['q'=>$q, 'mod'=>$x];
}
function bdiv($x,$y){
 global $bs, $bm, $bx2, $bx, $bd, $bdm, $log2;
 $arr=[];
 $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]))
 return ['q'=>[0], 'mod'=>$x];
 if($n==$t && toppart($x,$t,2)/toppart($y,$t,2) <4){
 $q=0;
 for(;;){
 $xx=bsub($x,$y);
 if(count($xx)==0)
 break;
 $x=$xx;
 $q++;
 }
 return ['q'=>[$q], 'mod'=>$x];
 }
 $shift2=floor(log($y[$t])/$log2)+1;
 $shift=$bs-$shift2;
 if($shift){
/////////////////////////////////////////////// Kiran Shakya solution
 $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;
 }
 $q=zeros($nmt+1);
 //array_push($arr, zeros($nmt));
 //array_push($arr, $y);
 //$y2=array_merge(...$arr);
 //////////////////////////////////// use array_merge straight away
 $y2=array_merge(zeros($nmt),$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([$q[$m]],$y2));
 if(count($x2)==0){
 $q[$m]--;
 $x2=bsub($x,bmul([$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;
 }
 while(count($q) > 1 && $q[count($q)-1]==0)
 $q=array_slice($q, 0, count($q)-1);
 while(count($x) > 1 && $x[count($x)-1]==0)
 $x=array_slice($x, 0, count($x)-1);
 return ['q'=>$q, 'mod'=>$x];
}

==========================> UPDATE

@Kiran Shakya idea to replace x=x.concat() with $x=array_merge(array(),$x); is actually working or at least I don't get any PHP error or warning on that, but start an infinite loop, which I have to shut manually. The script calling the toppart function, which operating with arbitrary precision numbers (multiply and add):

 function toppart(x,start,len) {
 var n=0
 while(start >= 0 && len > 0){
 n=n*bx2+x[start--]
 len--
 }
 return n
 }

The interesting part is, the JS returned for an example 70144566321522750 but the PHP returned 70144566321522751. In the later loop the differences are much bigger.
I have checked all numbers in both versions and all the same inputs: x,start,len,bx2. This can be a bug or one of them cannot handle big integers or what can be the reason?

Notice added Draw attention by szmegma
Bounty Started worth 100 reputation by szmegma
Source Link
szmegma
  • 249
  • 4
  • 9

Convert JavaScript function to PHP

I have a JS function, with array inputs.

For example:

x=[ 239709880, 250229420, 109667654, 196414465, 13098 ]
y=[ 78135241, 54642792, 249 ]

OR:

x=[ 0, 0, 0, 0, 0, 0, 1 ]
y=[ 78135241, 54642792, 249 ]

OR:

x=[ 49 ]
y=[ 33 ]

function bdiv(x,y) {
 var n=x.length-1, t=y.length-1, nmt=n-t, arr = []
 if(n < t || n==t && (x[n]<y[n] || n>0 && x[n]==y[n] && x[n-1]<y[n-1])) {
 arr['q']=[0]
 arr['mod']=x
 return arr
 }
 if(n==t && toppart(x,t,2)/toppart(y,t,2) <4) {
 var q=0, xx
 for(;;) {
 xx=bsub(x,y)
 if(xx.length==0) break
 x=xx; q++
 }
 arr['q']=[q]
 arr['mod']=x
 return arr
 }
 var shift, shift2
 shift2=Math.floor(Math.log(y[t])/log2)+1
 shift=bs-shift2
 if(shift) {
 x=x.concat()
 y=y.concat()
 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
 }
 var i, j, x2, y2,q=zeros(nmt+1)
 y2=zeros(nmt).concat(y)
 for(;;) {
 x2=bsub(x,y2)
 if(x2.length==0) break
 q[nmt]++
 x=x2
 }
 var yt=y[t], top=toppart(y,t,2)
 for(i=n; i>t; i--) {
 m=i-t-1
 if(i >= x.length)
 q[m]=1
 else if(x[i] == yt)
 q[m]=bm
 else
 q[m]=Math.floor(toppart(x,i,2)/yt)
 topx=toppart(x,i,3)
 while(q[m] * top > topx)
 q[m]--
 y2=y2.slice(1)
 x2=bsub(x,bmul([q[m]],y2))
 if(x2.length==0) {
 q[m]--
 x2=bsub(x,bmul([q[m]],y2))
 }
 x=x2
 }
 if(shift){
 for(i=0; i<x.length-1; i++)
 x[i]=(x[i]>>shift) | ((x[i+1] << shift2) & bm);
 x[x.length-1]>>=shift
 }
 while(q.length > 1 && q[q.length-1]==0)
 q=q.slice(0,q.length-1)
 while(x.length > 1 && x[x.length-1]==0)
 x=x.slice(0,x.length-1)
 arr['q']=q
 arr['mod']=x
 return arr;
}


What I have done under 5 days so far in PHP:

function bdiv($x,$y){
 global $bs, $bm, $bx2, $bx, $bd, $bdm, $log2;
 $arr=[];
 $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]))
 return ['q'=>[0], 'mod'=>$x];
 if($n==$t && toppart($x,$t,2)/toppart($y,$t,2) <4){
 $q=0;
 for(;;){
 $xx=bsub($x,$y);
 if(count($xx)==0)
 break;
 $x=$xx;
 $q++;
 }
 return ['q'=>[$q], 'mod'=>$x];
 }
 $shift2=floor(log($y[$t])/$log2)+1;
 $shift=$bs-$shift2;
 if($shift){
/////////////////////////////////////////////////// the problem start here with the concat()
 array_push($x,$x);
 array_push($y,$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;
 }
 $q=zeros($nmt+1);
 array_push($arr, zeros($nmt));
 array_push($arr, $y);
 $y2=array_merge(...$arr);
 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([$q[$m]],$y2));
 if(count($x2)==0){
 $q[$m]--;
 $x2=bsub($x,bmul([$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;
 }
 while(count($q) > 1 && $q[count($q)-1]==0)
 $q=array_slice($q, 0, count($q)-1);
 while(count($x) > 1 && $x[count($x)-1]==0)
 $x=array_slice($x, 0, count($x)-1);
 return ['q'=>$q, 'mod'=>$x];
}

So as I marked in the PHP code I have a problem with the array_push($x,$x), seems like this is not the equivalent of x=x.concat(). Array_push add the whole current $x values as a new element to the existing $x array:

$x=[ 1, 2, 3 ];
array_push($x,$x);
then $x will be [ 1, 2, 3, [ 1, 2, 3 ] ]

If I try to flatten the array ($x=array_merge(...$x);) then a new PHP error shows up: array_merge(): Argument #1 is not an array

I would really appreciate it if anyone have any idea, how to convert properly this JS function to a PHP version. Thanks in advance.

default

AltStyle によって変換されたページ (->オリジナル) /