The following function determines the maximum of two integers. It
works on my machine.
If (a[0] - a[1]) is negative, what's the first bit of: (unsigned)(a[0]
- a[1])? Is it 0 or 1?
<G mode=clinton> It depends partly on what "is" means. </>
If you mean the C expression a[0] - a[1] where both are type 'int',
that is negative IF a[0] < a[1] AND the subtraction doesn't overflow,
or equivalently the difference is within the range of 'int'. If the C
subtraction is negative, then the high bit of the conversion (by cast)
to 'unsigned' is reliably 1 IF 'unsigned int' has at least one more
magnitude bit than '(signed) int'; this is very common, but is not
required by the standard. Overflow (of a signed type) is Undefined
Behavior in the standard and formally anything can happen, the
canonical example of which in this newsgroup is that it may cause
demons to fly out your nose; in practice on most real implementations
you'll just get the wrong answer -- which is bad enough.
If you mean the mathematical integer a[0] - a[1], that is negative if
and only if a[0] < a[1]. But your C code does not reliably compute it,
and in general neither does any C program, since mathematical integers
are unbounded (loosely, infinite) and any C implementation must be
finite -- and even if it wasn't required to be, or in some other
language that formally isn't, any actual implementation still is.
int max(int n1, int n2)
{
int a[2];
a[0] = n1, a[1] = n2;
return a[((unsigned)(a[0] - a[1]) >> sizeof n1 * CHAR_BIT - 1)];
Absolutely nothing is accomplished by copying into a[0,1] and then
using those, and IM(subjective)O it _reduces_ clarity.
The representation of 'unsigned' is allowed to include padding bits,
in which case the shift amount you compute is too high -- and the
result again is undefined behavior, which in practice is likely wrong.
This will work for twos complement and sign-magnitude machines. I doubt
you'll ever encounter any other sort.
It will fail on ones complement machines where the subtraction gave the
value -0, and it will fail on any other sort of representation, for
example excess-N.
No, it will work in C for all allowed integer representations, as long
as the bit-width of unsigned is sufficient as described above. 1sC and
S&M representations can have negative-zero, but the conversion to
unsigned is done based on its _value_ which is still zero, not its
representation. Type-punning through a pointer or union or cheating on
non-prototyped argument type might have problems with non-2sC.
However its a very complicated way to compare two ints. If I found it
during code review, I'd force my developer to remove it.
Overly complicated AND unreliable.
By the way, this isn't a C question. Ask in comp.programming next time.
Well, parts of it are. Besides, it's kind of fun. <G>
- formerly david.thompson1 || achar(64) || worldnet.att.net