How about
unsigned int zerofill(unsigned int a, int b) {
return a >> b;
}
Or,
int zerofill(int a, int b) {
return ((unsigned int)a) >> b;
}
In C, the right shift operator acts as an arithmetic shift if its left operand is signed, or a logical shift if unsigned. It appears that the original PHP code is going to some lengths to get an unsigned shift using only a signed shift.
The C99 standard at section 6.5.7 says:
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.
This says clearly that to get zero bits shifted in, the operand must be either unsigned, or signed and positive. The only question is the behavior when the operand is signed and negative where the result is implementation defined. In practice, every implementation I've encountered has treated that case by sign extension so that the result still makes sense as a division by a power of two when integer values are stored as two's complement.
I don't have the reference at hand, but C89 said effectively the same thing, and established practice before the C standard was also consistent with this interpretation.