value range propagation for _bitwise_ OR
"Jérôme M. Berger"
jeberger at free.fr
Sat Apr 17 02:02:27 PDT 2010
Andrei Alexandrescu wrote:
> On 04/16/2010 11:43 PM, Steven Schveighoffer wrote:
>> Andrei Alexandrescu Wrote:
>>
>>> Looks great, thanks Jerome!
>>>
>>> Now, how about that case in which some or all of the ranges
>>> involved include negative values?
>>
>> I solved already signed values in terms of any valid unsigned
>> solution, see here:
>> http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=108869
>>
>>
>> The maxor with all the unsigned casts is the call to the unsigned
>> maxor. Ditto for minor.
>>
>> Also, see my one liner for unsigned maxor:
>>
>> http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=108916
>>
>>
>> All that is left is to find a quick (possibly one liner?) minor for
>> unsigned. Maybe there's a quicker signed solution, but the
>> complexity is already O(1) * complexity of unsigned.
>>
>> Also, someone pointed out that Jerome's highbit is equivalent to the
>> x86 bsr instruction (std.instrinsic.bsr).
>
> That looks good. I'm thinking of expressing minOR for unsigned in terms
> of maxOR for one's complement.
>
> We have min_a <= a <= max_a. This implies ~max_a <= ~a <= ~min_a.
>
> Wavehanding follows.
>
> We're looking for the numbers a and b that minimize the number of bits
> in a|b. Those choices for a and b would then maximize the number of bits
> in ~a|~b. So:
>
> minOR == maxOR(~max_a, ~min_a, ~max_b, ~min_b)
>
> Works?
>
Assuming you meant:
minOR == ~maxOR(~max_a, ~min_a, ~max_b, ~min_b)
Then that was my first idea too but it is *very* conservative. In
my tests it only gave the best result for 0.1% of the time. So we'll
have to do it the hard way:
==============================8<------------------------------
uint32_t minOr (uint32_t minA, uint32_t minB,
uint32_t maxA, uint32_t maxB)
{
assert (minA <= maxA);
assert (minB <= maxB);
if (minA == 0) return minB;
if (minB == 0) return minA;
uint32_t a = maxA ^ minA;
if (a != 0) {
a = ((1 << (highbit (a)+1)) - 1) & ~minA & minB;
if (a != 0)
a = (1 << highbit (a)) - 1;
}
a = minA & ~a;
uint32_t b = maxB ^ minB;
if (b != 0) {
b = ((1 << (highbit (b)+1)) - 1) & ~minB & minA;
if (b != 0)
b = (1 << highbit (b)) - 1;
}
b = minB & ~b;
return min (minA|b, a|minB);
}
------------------------------>8==============================
The one-liner is left as an exercise to the readers (since it has
the same performance anyway).
Jerome
--
mailto:jeberger at free.fr
http://jeberger.free.fr
Jabber: jeberger at jabber.fr
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 198 bytes
Desc: OpenPGP digital signature
URL: <http://lists.puremagic.com/pipermail/digitalmars-d/attachments/20100417/fac6517e/attachment.pgp>
More information about the Digitalmars-d
mailing list