PHP مكافئ javaScript >>> التحول يمينًا مع مشغلي Zero Fill Bitwise؟

StackOverflow https://stackoverflow.com/questions/2642026

سؤال

هل لي أن أعرف كيف يمكنني فعل php >>>؟ هؤلاء المشغلين غير متوفرون في PHP ، ولكنه متاح في JavaScript.

لقد تمكنت للتو من اكتشاف وظيفة على النحو التالي:

function zeroFill($a, $b) 
{ 
    $z = hexdec(80000000); 
        if ($z & $a) 
        { 
            $a = ($a>>1); 
            $a &= (~$z); 
            $a |= 0x40000000; 
            $a = ($a>>($b-1)); 
        } 
        else 
        { 
            $a = ($a>>$b); 
        } 
        return $a; 
}

لكن لسوء الحظ ، لا يعمل بشكل مثالي.

على سبيل المثال: -1149025787 >>> 0 جافا سكريبت إرجاع 3145941509 PHP Zerofill () Return 0

هل كانت مفيدة؟

المحلول 4

لقد درست حول الشبكات وخرجت بوظيفة Zerofill الخاصة بي ، القاعدة على التفسير المقدم. هذه الطريقة تعمل لبرنامجي.

الق نظرة:

function zeroFill($a,$b) {
    if ($a >= 0) { 
        return bindec(decbin($a>>$b)); //simply right shift for positive number
    }

    $bin = decbin($a>>$b);

    $bin = substr($bin, $b); // zero fill on the left side

    $o = bindec($bin);
    return $o;
}

نصائح أخرى

/**
 * The >>> javascript operator in php x86_64
 * Usage: -1149025787 >>> 0 ---> rrr(-1149025787, 0) === 3145941509
 * @param int $v
 * @param int $n
 * @return int
 */
function rrr($v, $n)
{
    return ($v & 0xFFFFFFFF) >> ($n & 0x1F);
}

/**
 * The >> javascript operator in php x86_64
 * @param int $v
 * @param int $n
 * @return int
 */
function rr($v, $n)
{
    return ($v & 0x80000000 ? $v | 0xFFFFFFFF00000000 : $v & 0xFFFFFFFF) >> ($n & 0x1F);
}


/**
 * The << javascript operator in php x86_64
 * @param int $v
 * @param int $n
 * @return int
 */
function ll($v, $n)
{
    return ($t = ($v & 0xFFFFFFFF) << ($n & 0x1F)) & 0x80000000 ? $t | 0xFFFFFFFF00000000 : $t & 0xFFFFFFFF;
}

استمتع بها.

مرتين أسرع للأرقام السلبية مثل استخدام التحويلات العشرية الثنائية

function zerofill($a,$b) { 
    if($a>=0) return $a>>$b;
    if($b==0) return (($a>>1)&0x7fffffff)*2+(($a>>$b)&1);
    return ((~$a)>>$b)^(0x7fffffff>>($b-1)); 

لقد بحثت كثيرًا في هذا الأمر ، حيث جمعت أكثر من 11 إصدارًا من مشاريع Stackoverflow والمصادر المفتوحة ، ولم يعمل أي منها. لكن أخيرًا ، وجدت الحل.

لمزيد من التفاصيل ، والتوضيح المباشر ، والاختبارات والأمثلة ، تحقق من سؤالي وإجابتي:
التحول الأيمن غير الموقّع / التحول الأيمن الصفر في PHP (ما يعادل Java / JavaScript)

function unsignedRightShift($a, $b) {
    if ($b >= 32 || $b < -32) {
        $m = (int)($b/32);
        $b = $b-($m*32);
    }

    if ($b < 0) {
        $b = 32 + $b;
    }

    if ($b == 0) {
        return (($a>>1)&0x7fffffff)*2+(($a>>$b)&1);
    }

    if ($a < 0) 
    { 
        $a = ($a >> 1); 
        $a &= 0x7fffffff; 
        $a |= 0x40000000; 
        $a = ($a >> ($b - 1)); 
    } else { 
        $a = ($a >> $b); 
    }

    return $a; 
}

وظيفتك لا تعمل لأن متى $b == 0, ، التعبير

$a >> -1

سيتم تقييمه ، والذي يعود 0.

بافتراض آلات 32 بت ، يمكنك إضافة حالة خاصة:

if ($z & $a) {
  if ($b == 0)
    return $a + 0x100000000;
  else {
    ...

لست متأكدًا مما إذا كان هذا يعمل لصالح PHP ، فقد تمكنت من العمل مع C#.

int a, b, result;
//Instead of 
result = a >>> b;
//I do
result = (int)((uint)a >> b);

لقد وجدت ذلك عن طريق تصحيح الأخطاء في الكود الذي يستخدم >>> مقارنته مع إصدار C# من الكود الذي قمت بتحويله من JavaScript. أثناء المحاولة مع b = 0, ، واستخدام آلة حاسبة علمية لرؤية نتيجة مختلفة من السداسي الأمنية/ديسمبر >> و >>> إنتاج بواسطة JavaScript. متي a سلبي ، >>> في الواقع يجعل AA غير موقعة.

لست متأكدًا مما إذا كان هذا يناسب كل السيناريو ، ولكن لحالتي >>> هو لتجزئة MD5. أن أكون قادرًا على إنتاج ناتج مماثل ، فأنا راضٍ تمامًا عن النتيجة.

امل ان يساعد

لكل من 32 بت (php_int_size == 4) وأعداد صحيحة 64 بت (php_int_size == 8):

function SHR
($x, $c)
{
    $x = intval ($x); // Because 13.5 >> 0 returns 13. We follow.

    $nmaxBits = PHP_INT_SIZE * 8;
    $c %= $nmaxBits;

    if ($c)
        return $x >> $c & ~ (-1 << $nmaxBits - $c);
    else
        return $x;
}

هذا يعمل بالنسبة لي

function RRR($a, $b){
    return (int)((float)$a/pow(2,(int)$b));
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top