Can Birisi port bu C?

2 Cevap php

Ben hiçbir başarı ile, C portuna bu çalışırken son birkaç saat geçirdim. Birisi lütfen yardım edebilir?

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;
}

2 Cevap

Nasıl hakkında

unsigned int zerofill(unsigned int a, int b) {
    return a >> b;
}

Ya da,

int zerofill(int a, int b) {
    return ((unsigned int)a) >> b;
}

C, sağ shift operatörü sol işlenen imzalanmış ise bir aritmetik öteleme, ya da mantıksal bir vardiya imzasız gibi davranır. Bu orijinal PHP kodu yalnızca imzalı bir vardiya kullanarak imzasız bir vardiya almak için bazı uzunlukları gidiyor görünüyor.

Bölüm 6.5.7 de C99 standardı diyor ki:

The result of E1 >> E2 is E1 right-shifted E2 bit positions. If E1 has an unsigned type or if E1 has a signed type and a nonnegative value, the value of the result is the integral part of the quotient of E1 / 2^E2. If E1 has a signed type and a negative value, the resulting value is implementation-defined.

Bu sıfır bit kaydırılır almak için bu, işlenen imzasız veya imzalı ve pozitif ya da olmalıdır açıkça söylüyor. Tek soru sonuç tanımlanan uygulamasıdır nerede işlenen imzalanmış ve olumsuz bir davranıştır. Tamsayı değerleri ikinin tamamlayıcısı olarak depolandığı zaman sonuç yine ikisinin bir güç tarafından bir bölümü olarak mantıklı, böylece pratikte, karşılaştığım her uygulama işaret uzantısı tarafından bu davayı tedavi etmiştir.

Ben eldeki başvuru yok, ama C89 etkili aynı şeyi söyledi, ve kurulan uygulama C standardında önce de bu yorumun ile uyumlu idi.

Denenmemiş, ancak daha sonra kod çoğu aynıdır.

int zerofill(int a, int b) {
    int z = 0x80000000;
    if (z & a) {
        a = a >> 1;
        a &= ~z;
        a |= 0x40000000;
        a = a >> (b - 1);
    } else {
        a = a >> b;
    }
    return a;
}