[m-rev.] for review: add bitwise rotations for uint32s
Julien Fischer
jfischer at opturion.com
Sun Mar 28 03:49:15 AEDT 2021
Hi Zoltan,
On Sun, 28 Mar 2021, Zoltan Somogyi wrote:
> 2021-03-28 02:22 GMT+11:00 "Julien Fischer" <jfischer at opturion.com>:
>> + % unchecked_rotate_left(U, D) = N:
>> + %
>> + % N is the value obtained by rotating the binary representation of U
>> + % left by the lowest 5 bits of D.
>> + %
>> +:- func unchecked_rotate_left(uint32, uint) = uint32.
>
> I would reword the end of the comment as "by an amount given by the lowest ..."
Done.
,,,
>> +rotate_left(X, N) =
>> + ( if N < 32u then
>> + unchecked_rotate_left(X, N)
>> + else
>> + func_error($pred, "second argument exceeds 31 bits")
>> + ).
>
> s/second argument/shift amount/
Perhaps "rotate amount" rather than "shift amount"?
>> +:- pragma foreign_proc("C",
>> + unchecked_rotate_left(X::in, N::in) = (Result::out),
>> + [will_not_call_mercury, promise_pure, thread_safe],
>> +"
>> + N &= 31;
>> + // This implementation is from https://blog.regehr.org/archives/1063.
>> + // It is intended to avoid undefined behaviour in C and be recognisable by
>> + // C compilers as a rotate operation. (On architectures that have a rotate
>> + // instruction
>
> Add a comma after "instruction".
Done.
>> + N &= 31;
>> + Result = (X << (int) N) | (X >> (int) (-N & 31));
>> +").
>> +
>> +:- pragma foreign_proc("Java",
>> + unchecked_rotate_left(X::in, N::in) = (Result::out),
>> + [will_not_call_mercury, promise_pure, thread_safe],
>> +"
>> + Result = java.lang.Integer.rotateLeft(X, N);
>> +").
>
> The Java version has no N &= 31. Why?
>
> And the same for the _right versions.
It's unecessary. The rotateLeft and rotateRight methods in Java
do that anyway.
>> +*** Test 'rotate_left' ***
>
> I would change the test case code to print the results of unchecked_rotate_dir for a given
> pair of input args just after rotate_dir, so that these two lines would be next to each other
> (and lined up to make a visual diff trivial).
>
>> + rotate_left(00000000000000000000000000000001, 0) = 00000000000000000000000000000001
>> +unchecked_rotate_left(00000000000000000000000000000001, 0) = 00000000000000000000000000000001
>
>> +:- func to_binary_string_lz(uint32::in) = (string::uo) is det.
>
> What is the _lz for?
lz == leading zeros
> We have string.int_to_base_string in the standard library. This looks like a case for
> adding unsigned and size-specific versions of it as well. In fact, any kind of conversion
> to string that exists for any integer type should exist for all ten integer types.
True, I'll look into adding the missing ones.
> The diff is otherwise fine.
Thanks for the review.
Julien.
More information about the reviews
mailing list