2010-09-29 10 views
6

Jak napisać to wyrażenie C w J? (Gdzie x wejście jest liczbą całkowitą, a a jest zmienne tymczasowe)Jak napisać to wyrażenie C w J?

((a= ~x & (~x >> 1)) ^= a ? 0 : (a^(a & (a - 1))) | (a^(a & (a - 1))) << 1); 

.

Edit:

W bardziej czytelnej formie:

int a = (~x) & ((~x) >> 1); 
    if (a == 0) return 0; 
    int b = a^(a & (a - 1)); 
    return b | (b << 1); 
+11

W jaki sposób znaleźć drania, który to napisał? – GManNickG

+0

To nie jest praca domowa, ale było to 1 wyzwanie. Po rozwiązaniu tego po prostu pomyślałem, że przez dłuższy czas nie grałem z J, i zapomniałem o jego składni. Myślałem, że niektórzy tutaj będą. – Margus

+3

To wyrażenie powoduje niezdefiniowane zachowanie. Podwyrażenie '((a = ~ x & (~ x >> 1))^= a' powoduje dwie niezmodyfikowane modyfikacje do' a'. "Bardziej czytelna forma" nie powoduje niezdefiniowanego zachowania, więc nie jest to takie samo rzecz. –

Odpowiedz

5

Bez badań, podstawowe transkrypcji byłoby coś takiego:

Shift =: (33 b.) 
And =: (17 b.) 
Not =: (26 b.) 
Xor =: (22 b.) 
Or =: (23 b.) 

BastardFunction =: 3 : 0 
    a =. (Not y) And (_1 Shift (Not y)) 
    if. a do. 
    b =. a Xor (a And a - 1) 
    (1 Shift b) Or b 
    else. 
    0 
    end. 
) 

Ale nie może być mądrzejszy podejście.

+0

Hmmm, ja nie dostać 0 bardzo często ... to znaczy, nigdy. – MPelletier

+0

zatwierdzony do wartości 0-9 . uzyskać ten sam wynik, jak w postaci uproszczonej. – MPelletier

+0

(2^31) -3 (2^31) -2, i (2^31) -1 powrócimy 0. – MPelletier

3

Oto mały analyzis (z "czytelnej formie" wersji):

usnigned int nx = ~x; // I suppose it's unsigned 
int a = nx & (nx >> 1); 
// a will be 0 if there are no 2 consecutive "1" bits. 
// or it will contain "1" in position N1 if nx had "1" in positions N1 and N1 + 1 
if (a == 0) return 0; // we don't have set bits for the following algorithm 
int b = a^(a & (a - 1)); 
// a - 1 : will reset the least 1 bit and will set all zero bits (say, NZ) that were on smaller positions 
// a & (a - 1) : will leave zeroes in all (NZ + 1) LSB bits (because they're only bits that has changed 
// a^(a & (a - 1)) : will cancel the high part, leaving only the smallest bit that was set in a 
// so, for a = 0b0100100 we'll obtain a power of two: b = 0000100 
return b | (b << 1);  
// knowing that b is a power of 2, the result is b + b*2 => b*3 

Wydaje się, że algorytm szuka pierwszych 2 (począwszy od LSB) kolejnych bitów 0 w zmiennej x. Jeśli nie ma żadnych, to wynik jest 0. Jeśli zostaną znalezione, powiedz na pozycji PZ, wynik będzie zawierać dwa set bitów: PZ i PZ+1.

Powiązane problemy