Reputation: 20038
How do I write this C expression in J? (where x
is input integer, and a
is temporary variable)
((a= ~x & (~x >> 1)) ^= a ? 0 : (a ^ (a & (a - 1))) | (a ^ (a & (a - 1))) << 1);
.
In a more readable form:
int a = (~x) & ((~x) >> 1);
if (a == 0) return 0;
int b = a ^ (a & (a - 1));
return b | (b << 1);
Upvotes: 6
Views: 744
Reputation: 16677
Without testing, the basic transcription would be something like this:
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.
)
But there could be a smarter approach.
Upvotes: 5
Reputation: 14870
Here is a small analyzis (of the "readable form" version):
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
It seems that the algorithm is looking for the first 2 (starting from LSB) consecutive 0
bits in the x
variable.
If there aren't any, then the result is 0.
If they are found, say on position PZ
, then the result will contain two set bits: PZ
and PZ+1
.
Upvotes: 3