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
.
W jaki sposób znaleźć drania, który to napisał? – GManNickG
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
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. –