Plea for Unsigned Binary operators and a few more...
In doing some crypto programming in Lisp I ran into a need for bit rotate operators. And just as surely, stumbled into the demand that INT32 and INT64 represent SIGNED-BYTE quantities… uh oh…Signed arithmetic is asymmetric in left / right shift operators. In left shift a zero bit is shifted into the LSB of the register, while in right shifts the sign bit is propagated rightward. Hence, whenever a bit pattern (usually unsigned in crypto work) has its sign bit set, you can simply OR together left shifted and right shifted components to achieve a bit pattern rotate.
I came up with a “fast” (?) solution that dispenses with any test and branch by inventing a CNOT (conditional one’s complement) function:
(defun cnot (x)
(int64-logxor x
(int64>> x 63)))
so that the propagating sign bit effects are removed when defining rotate operators:
(defun rotl (x n)
(int64-logxor
(int64>> x (- 64 n))
(int64<< (cnot x) n)))
(defun rotr (x n)
(int64-logxor
(int64>> x n)
(int64<< (cnot x) (- 64 n))))
But it sure would be nice to have some ROT operators (ROTL, ROTR).
In addition, I can think of no instance where defaulting to unsigned behavior would be any different in arithmetic than signed, except in the right shift operation. So for this one case, there is the Symmetric case of Unsigned right-shift, and the Asymmetric case of Signed right-shift. Why not just default to unsigned operands always, and implement two different kinds of right-shift?
Am I missing any cases?
- DM