stdc_bit_ceil(3) and wrapping
Alejandro Colomar
alx.manpages@gmail.com
Fri Dec 30 22:33:01 GMT 2022
Hi Yann,
On 12/30/22 21:33, Alejandro Colomar wrote:
> On 12/30/22 21:18, Yann Droneaud wrote:
>> What's wrong with the following ?
[...]
>
>>
>> unsigned long max = upper_bound - 1;
>> unsigned long mask = ULONG_MAX >> __builtin_clzl(max);
>
> I hate coding these magic operations out of a function, when I can give it a
> meaningful name. That reads to me as a magic trick that many maintainers that
> read it after me will blame me for having to parse it.
>
> Moreover, it requires you to have the special case for 0 at the top, which I
> don't want.
I reconsidered; my -1 was equally magic. And by calling it 'mask',
ULONG_MAX >> n is something not so magic.
The builtin still has the problem that it requires special-casing 0, so I prefer
the C23 call, which provides the behavior I want for 0:
unsigned long
shadow_random_uniform(unsigned long upper_bound)
{
unsigned long r, max, mask;
max = upper_bound - 1;
mask = ULONG_MAX >> leading_zerosul(max);
do {
r = shadow_random();
r &= mask; // optimization
} while (r > max);
return r;
}
And, now I don't need to add a wrapper around bit_ceil() that removes the UB.
stdc_leading_zerosul() is just fine for this use case.
Cheers,
Alex
--
<http://www.alejandro-colomar.es/>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: OpenPGP_signature
Type: application/pgp-signature
Size: 833 bytes
Desc: OpenPGP digital signature
URL: <https://sourceware.org/pipermail/libc-alpha/attachments/20221230/4ce01779/attachment.sig>
More information about the Libc-alpha
mailing list