Velocity Reviews > compare a large number of variables

# compare a large number of variables

Netocrat
Guest
Posts: n/a

 08-18-2005
On Thu, 18 Aug 2005 20:01:31 +0000, Mark wrote:
> "Netocrat" <(E-Mail Removed)> wrote in message
> news(E-Mail Removed)...
>> On Thu, 18 Aug 2005 17:11:25 +0000, Michael Wojcik wrote:
>>> In article <(E-Mail Removed)>, Netocrat
>>> <(E-Mail Removed)> writes:
>>>> On Tue, 16 Aug 2005 23:55:15 -0700, Einar wrote:
>>>>
>>>> > Yes, your suggestions work perfectly, but I was mor looking for a
>>>> > nice bit operator to operate on all my variables and then to compare
>>>> > it with the value. something like (a|b|c|d...z) != value (this wont
>>>> > work however... ).
>>>>
>>>>
>>>> if ( !( ((a|b|c|d...z) == value) && ((a&b&c&d...z) == value) ) )
>>>> /* one or more of a,b,c,d...z is not equal to value */
>>>
>>> Or the similarly silly:
>>>
>>> if (a^value|b^value|c^value|...|z^value)
>>> /* one or more of a,b,c,...,z is not equal to value */

>>
>> No that doesn't work. In the case of one variable with a==1, value==1
>> then a^value is false. I can't see a way to rearrange it using bitwise
>> or/and to work.

>
> Albeit ugly, this should work:
>
> if(a-b|b-c|c-d|d-e /* ... */)
> puts("mismatched");
> else
> puts("pick one... they're all the same");

All zero? Overflow?

Also it doesn't use the ^ operator - but you my not have been responding
directly to what I said (which was intended to mean that I can't see a way
to rearrange the expression so that it works as intended, keeping the ^
expressions and using other bitwise operators as required - and I wouldn't
have objected to an overall negation operator if that had been necessary).

--
http://members.dodo.com.au/~netocrat

Netocrat
Guest
Posts: n/a

 08-18-2005
On Thu, 18 Aug 2005 13:34:06 -0700, Tim Rentsch wrote:
> Netocrat <(E-Mail Removed)> writes:
>> On Thu, 18 Aug 2005 13:03:34 -0700, Tim Rentsch wrote:
>> > Netocrat <(E-Mail Removed)> writes:
>> >> On Thu, 18 Aug 2005 17:11:25 +0000, Michael Wojcik wrote:
>> >> > In article <(E-Mail Removed)>, Netocrat
>> >> > <(E-Mail Removed)> writes:
>> >> >> On Tue, 16 Aug 2005 23:55:15 -0700, Einar wrote:
>> >> >>
>> >> >> > Yes, your suggestions work perfectly, but I was mor looking for a
>> >> >> > nice bit operator to operate on all my variables and then to compare
>> >> >> > it with the value. something like (a|b|c|d...z) != value (this wont
>> >> >> > work however... ).
>> >> >>
>> >> >> How about (off the top of my head and untested):
>> >> >>
>> >> >> if ( !( ((a|b|c|d...z) == value) && ((a&b&c&d...z) == value) ) )
>> >> >> /* one or more of a,b,c,d...z is not equal to value */
>> >> >
>> >> > Or the similarly silly:
>> >> >
>> >> > if (a^value|b^value|c^value|...|z^value)
>> >> > /* one or more of a,b,c,...,z is not equal to value */
>> >>
>> >> No that doesn't work. In the case of one variable with a==1, value==1
>> >> then a^value is false.
>> >

>>
>> It's identical to my original comment except for the addition of a couple
>> of commas. Please be more specific.

>
> In the case of one variable with a==1, value==1 then a^value
> is false. The first branch of the 'if' is not taken; all
> elements of {a} are equal to value, or equivalently, none of
> the elements of {a} is not equal to value.
>
> The 'if' expression works just as the comment says it does.
> The remark of "No that doesn't work" is therefore, shall
> we say, less than totally accurate.

If the comment entirely defined the expected behaviour, then you would be
right. Actually though, the code is to be read as though followed by:

else
/* all variables are equal to value */

because the context of the thread is a search for a one-liner to determine
whether all variables are equal to a value or not. The example I
provided shows that as a one-liner it fails in at least one case.

--
http://members.dodo.com.au/~netocrat

Tim Rentsch
Guest
Posts: n/a

 08-18-2005
Netocrat <(E-Mail Removed)> writes:

> On Thu, 18 Aug 2005 13:03:34 -0700, Tim Rentsch wrote:
> > Netocrat <(E-Mail Removed)> writes:
> >> On Thu, 18 Aug 2005 17:11:25 +0000, Michael Wojcik wrote:
> >> > In article <(E-Mail Removed)>, Netocrat
> >> > <(E-Mail Removed)> writes:
> >> >> On Tue, 16 Aug 2005 23:55:15 -0700, Einar wrote:
> >> >>
> >> >> > Yes, your suggestions work perfectly, but I was mor looking for a
> >> >> > nice bit operator to operate on all my variables and then to compare
> >> >> > it with the value. something like (a|b|c|d...z) != value (this wont
> >> >> > work however... ).
> >> >>
> >> >> How about (off the top of my head and untested):
> >> >>
> >> >> if ( !( ((a|b|c|d...z) == value) && ((a&b&c&d...z) == value) ) )
> >> >> /* one or more of a,b,c,d...z is not equal to value */
> >> >
> >> > Or the similarly silly:
> >> >
> >> > if (a^value|b^value|c^value|...|z^value)
> >> > /* one or more of a,b,c,...,z is not equal to value */
> >>
> >> No that doesn't work. In the case of one variable with a==1, value==1
> >> then a^value is false.

> >

>
> It's identical to my original comment except for the addition of a couple
> of commas. Please be more specific.

In the case of one variable with a==1, value==1 then a^value
is false. The first branch of the 'if' is not taken; all
elements of {a} are equal to value, or equivalently, none of
the elements of {a} is not equal to value.

The 'if' expression works just as the comment says it does.
The remark of "No that doesn't work" is therefore, shall
we say, less than totally accurate.

Tim Rentsch
Guest
Posts: n/a

 08-18-2005
Netocrat <(E-Mail Removed)> writes:

> On Thu, 18 Aug 2005 13:34:06 -0700, Tim Rentsch wrote:
> > Netocrat <(E-Mail Removed)> writes:
> >> On Thu, 18 Aug 2005 13:03:34 -0700, Tim Rentsch wrote:
> >> > Netocrat <(E-Mail Removed)> writes:
> >> >> On Thu, 18 Aug 2005 17:11:25 +0000, Michael Wojcik wrote:
> >> >> > In article <(E-Mail Removed)>, Netocrat
> >> >> > <(E-Mail Removed)> writes:
> >> >> >> On Tue, 16 Aug 2005 23:55:15 -0700, Einar wrote:
> >> >> >>
> >> >> >> > Yes, your suggestions work perfectly, but I was mor looking for a
> >> >> >> > nice bit operator to operate on all my variables and then to compare
> >> >> >> > it with the value. something like (a|b|c|d...z) != value (this wont
> >> >> >> > work however... ).
> >> >> >>
> >> >> >> How about (off the top of my head and untested):
> >> >> >>
> >> >> >> if ( !( ((a|b|c|d...z) == value) && ((a&b&c&d...z) == value) ) )
> >> >> >> /* one or more of a,b,c,d...z is not equal to value */
> >> >> >
> >> >> > Or the similarly silly:
> >> >> >
> >> >> > if (a^value|b^value|c^value|...|z^value)
> >> >> > /* one or more of a,b,c,...,z is not equal to value */
> >> >>
> >> >> No that doesn't work. In the case of one variable with a==1, value==1
> >> >> then a^value is false.
> >> >
> >>
> >> It's identical to my original comment except for the addition of a couple
> >> of commas. Please be more specific.

> >
> > In the case of one variable with a==1, value==1 then a^value
> > is false. The first branch of the 'if' is not taken; all
> > elements of {a} are equal to value, or equivalently, none of
> > the elements of {a} is not equal to value.
> >
> > The 'if' expression works just as the comment says it does.
> > The remark of "No that doesn't work" is therefore, shall
> > we say, less than totally accurate.

>
> If the comment entirely defined the expected behaviour, then you would be
> right. Actually though, the code is to be read as though followed by:
>
> else
> /* all variables are equal to value */

not necessary to understand the point being made, nor, I feel
confident, what the poster intended. In any case that's
and if you want to make presumptions about something that
*wasn't* written then the burden is on you to state what
those presumptions are. Don't expect other people to read

> because the context of the thread is a search for a one-liner to determine
> whether all variables are equal to a value or not. The example I
> provided shows that as a one-liner it fails in at least one case.

the thread is a search for code to determine whether *any*
variables are *not* equal to a value. Which is exactly what
the posted code did.

Netocrat
Guest
Posts: n/a

 08-18-2005
>> >> On Thu, 18 Aug 2005 13:03:34 -0700, Tim Rentsch wrote:
>> >> > Netocrat <(E-Mail Removed)> writes:
>> >> >> On Thu, 18 Aug 2005 17:11:25 +0000, Michael Wojcik wrote:
>> >> >> > In article <(E-Mail Removed)>,
>> >> >> > Netocrat <(E-Mail Removed)> writes:
>> >> >> >> On Tue, 16 Aug 2005 23:55:15 -0700, Einar wrote:
>> >> >> >>
>> >> >> >> > Yes, your suggestions work perfectly, but I was mor looking
>> >> >> >> > for a nice bit operator to operate on all my variables and
>> >> >> >> > then to compare it with the value. something like
>> >> >> >> > (a|b|c|d...z) != value (this wont work however... ).
>> >> >> >>
>> >> >> >> How about (off the top of my head and untested):
>> >> >> >>
>> >> >> >> if ( !( ((a|b|c|d...z) == value) && ((a&b&c&d...z) == value) )
>> >> >> >> )
>> >> >> >> /* one or more of a,b,c,d...z is not equal to value */
>> >> >> >
>> >> >> > Or the similarly silly:
>> >> >> >
>> >> >> > if (a^value|b^value|c^value|...|z^value)
>> >> >> > /* one or more of a,b,c,...,z is not equal to value */
>> >> >>
>> >> >> No that doesn't work.

[...]
>> > The 'if' expression works ... The remark of "No that doesn't work" is
>> > therefore, shall we say, less than totally accurate.

Xors have always been a weak spot in my logic. You're right, the code
works as advertised as Pete attempted to point out elsewhere in his usual
understated style.

[...]

--
http://members.dodo.com.au/~netocrat

Mark
Guest
Posts: n/a

 08-19-2005

"Netocrat" <(E-Mail Removed)> wrote in message
news(E-Mail Removed)...
> On Thu, 18 Aug 2005 20:01:31 +0000, Mark wrote:
>> "Netocrat" <(E-Mail Removed)> wrote in message
>> news(E-Mail Removed)...
>>> On Thu, 18 Aug 2005 17:11:25 +0000, Michael Wojcik wrote:
>>>> In article <(E-Mail Removed)>, Netocrat
>>>> <(E-Mail Removed)> writes:
>>>>> On Tue, 16 Aug 2005 23:55:15 -0700, Einar wrote:
>>>>>
>>>>> > Yes, your suggestions work perfectly, but I was mor looking for a
>>>>> > nice bit operator to operate on all my variables and then to compare
>>>>> > it with the value. something like (a|b|c|d...z) != value (this wont
>>>>> > work however... ).
>>>>>
>>>>>
>>>>> if ( !( ((a|b|c|d...z) == value) && ((a&b&c&d...z) == value) ) )
>>>>> /* one or more of a,b,c,d...z is not equal to value */
>>>>
>>>> Or the similarly silly:
>>>>
>>>> if (a^value|b^value|c^value|...|z^value)
>>>> /* one or more of a,b,c,...,z is not equal to value */
>>>
>>> No that doesn't work. In the case of one variable with a==1, value==1
>>> then a^value is false. I can't see a way to rearrange it using bitwise
>>> or/and to work.

>>
>> Albeit ugly, this should work:
>>
>> if(a-b|b-c|c-d|d-e /* ... */)
>> puts("mismatched");
>> else
>> puts("pick one... they're all the same");

>
> All zero? Overflow?

Overflow is not possible, stare at it for a while and see if you can figure
out why

> Also it doesn't use the ^ operator

You didn't say it had to use the exclusive or operator ... you said bit
operator, no?
AFAIK the inclusive or operator is a bit operator... do you disagree?

- but you my not have been responding
> directly to what I said

I was.

> (which was intended to mean that I can't see a way
> to rearrange the expression so that it works as intended, keeping the ^

No, you said using bitwise operators, which I most definately did.

> expressions and using other bitwise operators as required - and I wouldn't
> have objected to an overall negation operator if that had been necessary).

Whatever that means.
Do you know what the code does? Obviously not if you're worried about
overflow

Netocrat
Guest
Posts: n/a

 08-19-2005
On Fri, 19 Aug 2005 15:11:10 +0000, Mark wrote:
> "Netocrat" <(E-Mail Removed)> wrote in message
> news(E-Mail Removed)...
>> On Thu, 18 Aug 2005 20:01:31 +0000, Mark wrote:
>>> "Netocrat" <(E-Mail Removed)> wrote in message
>>> news(E-Mail Removed)...
>>>> On Thu, 18 Aug 2005 17:11:25 +0000, Michael Wojcik wrote:
>>>>> In article <(E-Mail Removed)>, Netocrat
>>>>> <(E-Mail Removed)> writes:
>>>>>> On Tue, 16 Aug 2005 23:55:15 -0700, Einar wrote:
>>>>>>
>>>>>> > Yes, your suggestions work perfectly, but I was mor looking for a
>>>>>> > nice bit operator to operate on all my variables and then to compare
>>>>>> > it with the value. something like (a|b|c|d...z) != value (this wont
>>>>>> > work however... ).
>>>>>>
>>>>>>
>>>>>> if ( !( ((a|b|c|d...z) == value) && ((a&b&c&d...z) == value) ) )
>>>>>> /* one or more of a,b,c,d...z is not equal to value */
>>>>>
>>>>> Or the similarly silly:
>>>>>
>>>>> if (a^value|b^value|c^value|...|z^value)
>>>>> /* one or more of a,b,c,...,z is not equal to value */
>>>>
>>>> No that doesn't work. In the case of one variable with a==1, value==1
>>>> then a^value is false. I can't see a way to rearrange it using bitwise
>>>> or/and to work.
>>>
>>> Albeit ugly, this should work:
>>>
>>> if(a-b|b-c|c-d|d-e /* ... */)
>>> puts("mismatched");
>>> else
>>> puts("pick one... they're all the same");

>>
>> All zero?

Embarrassingly, my logic circuits have been malfunctioning in this
thread... as evidenced above (the xor code works contrary to my claim) and
here - the code performs correctly for all variables zero.

>> Overflow?

> Overflow is not possible, stare at it for a while and see if you can figure
> out why

Perhaps I don't understand the overflow requirements. And perhaps I
should have called it underflow instead of overflow. But by my
understanding, if a and b are unsigned and a == 0 and b > 0, then the
expression (a-b) results in an underflow, which is undefined behaviour.

I don't see that this would be changed by it being part of a greater
expression. But my strike rate in this thread hasn't been crash hot so
I'm not betting the bank on it...

Alternatively this could occur if both are signed int and a == INT_MIN
and b > 0, but as noted by Michael Wojcik the bitwise operators may result
in trap representations for signed types - so we should require unsigned
variables for portability.

>> Also it doesn't use the ^ operator

> You didn't say it had to use the exclusive or operator ... you said bit
> operator, no?

Right, but I wrote "rearranged" and intended that to mean retaining the
expressions with the ^ operator, but I can see how you might have
interpreted me differently. Anyhow as it turns out there is no need for
rearrangement as it works as is.

[...]
> Do you know what the code does?

It looks to me like it compares each variable to its neighbour by
subtracting one from the other; if any of the comparisons are unequal then
at least one bit will be set in the result and the bitwise or will
agglomerate any of these bits into the final result, which will be
non-zero only if any variable differs from its neighbour - and by chaining
neighbours this equates to if any variable differs from any of the rest.

[...]

--
http://members.dodo.com.au/~netocrat

Mark
Guest
Posts: n/a

 08-19-2005

"Mark" <(E-Mail Removed)> wrote in message
news:iEmNe.229\$(E-Mail Removed)...
>
> "Netocrat" <(E-Mail Removed)> wrote in message
> news(E-Mail Removed)...
>> On Thu, 18 Aug 2005 20:01:31 +0000, Mark wrote:
>>> "Netocrat" <(E-Mail Removed)> wrote in message
>>> news(E-Mail Removed)...
>>>> On Thu, 18 Aug 2005 17:11:25 +0000, Michael Wojcik wrote:
>>>>> In article <(E-Mail Removed)>, Netocrat
>>>>> <(E-Mail Removed)> writes:
>>>>>> On Tue, 16 Aug 2005 23:55:15 -0700, Einar wrote:
>>>>>>
>>>>>> > Yes, your suggestions work perfectly, but I was mor looking for a
>>>>>> > nice bit operator to operate on all my variables and then to
>>>>>> > compare
>>>>>> > it with the value. something like (a|b|c|d...z) != value (this wont
>>>>>> > work however... ).
>>>>>>
>>>>>>
>>>>>> if ( !( ((a|b|c|d...z) == value) && ((a&b&c&d...z) == value) ) )
>>>>>> /* one or more of a,b,c,d...z is not equal to value */
>>>>>
>>>>> Or the similarly silly:
>>>>>
>>>>> if (a^value|b^value|c^value|...|z^value)
>>>>> /* one or more of a,b,c,...,z is not equal to value */
>>>>
>>>> No that doesn't work. In the case of one variable with a==1, value==1
>>>> then a^value is false. I can't see a way to rearrange it using bitwise
>>>> or/and to work.
>>>
>>> Albeit ugly, this should work:
>>>
>>> if(a-b|b-c|c-d|d-e /* ... */)
>>> puts("mismatched");
>>> else
>>> puts("pick one... they're all the same");

>>
>> All zero? Overflow?

> Overflow is not possible, stare at it for a while and see if you can
> figure out why

Rather than 'not possible' let me rephrase and say 'not an issue'
unless the values are equal, there must be at least one bit set...
which will in turn cause the statement to work properly.

>> Also it doesn't use the ^ operator

> You didn't say it had to use the exclusive or operator ... you said bit
> operator, no?
> AFAIK the inclusive or operator is a bit operator... do you disagree?
>
> - but you my not have been responding
>> directly to what I said

> I was.

Well, actually I was also responding to the OP question, which as of yet you

>> (which was intended to mean that I can't see a way
>> to rearrange the expression so that it works as intended, keeping the ^

> No, you said using bitwise operators, which I most definately did.

And again, OP did not require exlusive or operator.

>
>> expressions and using other bitwise operators as required - and I
>> wouldn't
>> have objected to an overall negation operator if that had been
>> necessary).

> Whatever that means.

I realized what you meant after reading your post a 2nd time... should have
waited a minute before responding, but I do that frequently

> Do you know what the code does? Obviously not if you're worried about
> overflow

.... as it couldn't affect the outcome of the statement... it should work
properly regardless.

Much better, I'm happy now.
Mark

Netocrat
Guest
Posts: n/a

 08-19-2005
Mark wrote:
> Mark wrote:
>> Netocrat wrote:
>>> Mark wrote:
>>>>>> Netocrat wrote:

[...]
>>>>>>>
>>>>>>> if ( !( ((a|b|c|d...z) == value) && ((a&b&c&d...z) == value) ) )
>>>>>>> /* one or more of a,b,c,d...z is not equal to value */

[...]
>>>> Albeit ugly, this should work:
>>>>
>>>> if(a-b|b-c|c-d|d-e /* ... */)
>>>> puts("mismatched");
>>>> else
>>>> puts("pick one... they're all the same");
>>>
>>> All zero? Overflow?

>> Overflow is not possible, stare at it for a while and see if you can
>> figure out why

> Rather than 'not possible' let me rephrase and say 'not an issue'
> unless the values are equal, there must be at least one bit set...
> which will in turn cause the statement to work properly.

As far as I understand, overflow/underflow invokes behaviour not covered
by the standard, which may include setting all bits to zero.

[...]
> Well, actually I was also responding to the OP question, which as of yet

What do you find deficient in my suggestion above, or the alternative
I gave which got snipped:

if ( ((a|b|c|d...z)&a&b&c&d...z) != value )
/* one or more of a,b,c,d...z is not equal to value */
?

> I realized what you meant after reading your post a 2nd time... should have
> waited a minute before responding, but I do that frequently

I can relate.

[...]
--
http://members.dodo.com.au/~netocrat

Mark
Guest
Posts: n/a

 08-19-2005

"Netocrat" <(E-Mail Removed)> wrote in message
news(E-Mail Removed)...
> [attributions cleaned up and simplified]
> Mark wrote:
>> Mark wrote:
>>> Netocrat wrote:
>>>> Mark wrote:
>>>>>>> Netocrat wrote:

> [...]
>>>>>>>>
>>>>>>>> if ( !( ((a|b|c|d...z) == value) && ((a&b&c&d...z) == value) ) )
>>>>>>>> /* one or more of a,b,c,d...z is not equal to value */

> [...]
>>>>> Albeit ugly, this should work:
>>>>>
>>>>> if(a-b|b-c|c-d|d-e /* ... */)
>>>>> puts("mismatched");
>>>>> else
>>>>> puts("pick one... they're all the same");
>>>>
>>>> All zero? Overflow?
>>> Overflow is not possible, stare at it for a while and see if you can
>>> figure out why

>> Rather than 'not possible' let me rephrase and say 'not an issue'
>> unless the values are equal, there must be at least one bit set...
>> which will in turn cause the statement to work properly.

>
> As far as I understand, overflow/underflow invokes behaviour not covered
> by the standard, which may include setting all bits to zero.

I thought it was covered... no?

H.2.2 Integer types
[#1] The signed C integer types int, long int, long long
int, and the corresponding unsigned types are compatible
with LIA-1. If an implementation adds support for the LIA-1
exceptional values integer_overflow and undefined, then
those types are LIA-1 conformant types. C's unsigned
integer types are ``modulo'' in the LIA-1 sense in that
overflows or out-of-bounds results silently wrap. An
implementation that defines signed integer types as also
being modulo need not detect integer overflow, in which
case, only integer divide-by-zero need be detected.

> [...]
>> Well, actually I was also responding to the OP question, which as of yet

>
> What do you find deficient in my suggestion above, or the alternative
> I gave which got snipped:
> if ( ((a|b|c|d...z)&a&b&c&d...z) != value )
> /* one or more of a,b,c,d...z is not equal to value */

I didn't see this one... it must have been elsethread.
As for deficiency, consider:
a = b = d = f = INT_MAX;
c = -1;

Regarding the one above, I didn't examine it...
The text which followed your suggestion was what prompted me to post.
<repost neocrat quote>
> No that doesn't work. In the case of one variable with a==1, value==1
> then a^value is false. I can't see a way to rearrange it using bitwise
> or/and to work.

I did see a way to arrange it using a bitwise or, so I posted my solution

Mark