Determine the maximum of two integers.

Discussion in 'C Programming' started by lovecreatesbea...@gmail.com, Nov 18, 2007.

1. Guest

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?

#include <limits.h>

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)];
}

, Nov 18, 2007

2. Mark McIntyreGuest

wrote:
> 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?
>
>
> #include <limits.h>
>
> 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)];
> }
>
>
> Thank you for your time

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.

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.

By the way, this isn't a C question. Ask in comp.programming next time.

Mark McIntyre, Nov 18, 2007

3. \$)CHarald van D)&kGuest

On Sun, 18 Nov 2007 12:33:32 +0000, Mark McIntyre wrote:
> wrote:
>> 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?
>>
>>
>> #include <limits.h>
>>
>> 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)];
>> }
>>
>>
>> Thank you for your time

>
> 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,

-0 is positive zero, and when the subtraction generates that, there are
no extra problems.

The subtraction is only allowed to give negative zero when both n1 and n2
are zero, and one or both of them is negative. In this case, the cast to
unsigned gives plain zero, meaning a[0] would be returned, which is a
valid option when n1 == n2. Negative zero is not smaller or larger than
positive zero for C integers, even though other systems may differ.

> and it will fail on any other sort of representation, for
> example excess-N.

Such a representation is not allowed.

The code may also fail if unsigned int has padding bits, by the way, for
at least two reasons. Firstly, there is no guarantee that
UINT_MAX > INT_MAX. Secondly, the behaviour of the right-shift is
undefined.

\$)CHarald van D)&k, Nov 18, 2007
4. Mark McIntyreGuest

ï¿½Harald van DÄ³k wrote:
> -0 is positive zero, and when the subtraction generates that, there are
> no extra problems.

You sure? The bitpattern of -0 is all-ones I think.

>> and it will fail on any other sort of representation, for
>> example excess-N.

>
> Such a representation is not allowed.

By a conforming C compiler.

> The code may also fail if unsigned int has padding bits, by the way, for
> at least two reasons. Firstly, there is no guarantee that
> UINT_MAX > INT_MAX. Secondly, the behaviour of the right-shift is
> undefined.

I belive UINT_MAX must be at least equal to INT_MAX however?

Mark McIntyre, Nov 18, 2007
5. Guest

On Nov 18, 3:07 pm, Mark McIntyre <> wrote:
> I belive UINT_MAX must be at least equal to INT_MAX however?

UINT_MAX >= INT_MAX >= 32767

x >= y does not guarantee x > y.

, Nov 18, 2007
6. \$)CHarald van D)&kGuest

On Sun, 18 Nov 2007 13:07:55 +0000, Mark McIntyre wrote:
> ï¿½Harald van DÄ³k wrote:
>> -0 is positive zero, and when the subtraction generates that, there are
>> no extra problems.

>
> You sure? The bitpattern of -0 is all-ones I think.

The bit pattern of -0 is all zeroes, since -0 is plain old zero. The bit
pattern of ~0 is all ones, and that is allowed to be negative zero. You
can't create negative zero except by bit manipulation; it's simply not
allowed, even if it would make sense for the processor.

>>> and it will fail on any other sort of representation, for example
>>> excess-N.

>>
>> Such a representation is not allowed.

>
> By a conforming C compiler.

Yes.

>> The code may also fail if unsigned int has padding bits, by the way,
>> for at least two reasons. Firstly, there is no guarantee that UINT_MAX
>> > INT_MAX. Secondly, the behaviour of the right-shift is undefined.

>
> I belive UINT_MAX must be at least equal to INT_MAX however?

Correct.

\$)CHarald van D)&k, Nov 18, 2007
7. Mark McIntyreGuest

wrote:
> On Nov 18, 3:07 pm, Mark McIntyre <> wrote:
>> I belive UINT_MAX must be at least equal to INT_MAX however?

>
> UINT_MAX >= INT_MAX >= 32767
>
> x >= y does not guarantee x > y.

I'm aware of that. Hence the words "at least equal".

Mark McIntyre, Nov 18, 2007
8. Mark McIntyreGuest

ï¿½Harald van DÄ³k wrote:
> On Sun, 18 Nov 2007 13:07:55 +0000, Mark McIntyre wrote:
>> ï¿½Harald van DÄ³k wrote:
>>> -0 is positive zero, and when the subtraction generates that, there are
>>> no extra problems.

>> You sure? The bitpattern of -0 is all-ones I think.

>
> The bit pattern of -0 is all zeroes, since -0 is plain old zero. The bit
> pattern of ~0 is all ones, and that is allowed to be negative zero. You
> can't create negative zero except by bit manipulation; it's simply not
> allowed, even if it would make sense for the processor.

Euh, I think we're at cross purposes.
-0 is negative zero
+0 is positive zero, plain old zero.

Not a C question however.
FUs set to

http://en.wikipedia.org/wiki/Ones_complement#Ones.27_complement

Mark McIntyre, Nov 18, 2007
9. \$)CHarald van D)&kGuest

On Sun, 18 Nov 2007 14:42:35 +0000, Mark McIntyre wrote:
> ï¿½Harald van DÄ³k wrote:
>> On Sun, 18 Nov 2007 13:07:55 +0000, Mark McIntyre wrote:
>>> ï¿½Harald van DÄ³k wrote:
>>>> -0 is positive zero, and when the subtraction generates that, there
>>>> are no extra problems.
>>> You sure? The bitpattern of -0 is all-ones I think.

>>
>> The bit pattern of -0 is all zeroes, since -0 is plain old zero. The
>> bit pattern of ~0 is all ones, and that is allowed to be negative zero.
>> You can't create negative zero except by bit manipulation; it's simply
>> not allowed, even if it would make sense for the processor.

>
> Euh, I think we're at cross purposes. -0 is negative zero
> +0 is positive zero, plain old zero.

In C (which is the topic of this newsgroup), -0 is an expression which
evaluates to positive zero. Always, regardless of the representation of
integers. It was obvious that you meant negative zero, and I did address
the message as if you had said negative zero later on, but -0 is not a
good notation for it here.

\$)CHarald van D)&k, Nov 18, 2007
10. jacob naviaGuest

Mark McIntyre wrote:
> ï¿½Harald van DÄ³k wrote:
>> -0 is positive zero, and when the subtraction generates that, there
>> are no extra problems.

>
> You sure? The bitpattern of -0 is all-ones I think.
>

You think?

Gosh McIntyre!

-0 is minus zero is zero!

And that is a bit pattern of all ZEROS!

~0 is a bit pattern of all ones!

--
jacob navia
jacob at jacob point remcomp point fr
logiciels/informatique
http://www.cs.virginia.edu/~lcc-win32

jacob navia, Nov 18, 2007
11. Mark McIntyreGuest

On Sun, 18 Nov 2007 17:55:21 +0100, in comp.lang.c , jacob navia
<> wrote:

>Mark McIntyre wrote:
>> ?Harald van D?k wrote:
>>> -0 is positive zero, and when the subtraction generates that, there
>>> are no extra problems.

>>
>> You sure? The bitpattern of -0 is all-ones I think.
>>

>
>You think?

I certainly did.

>Gosh McIntyre!

Slainte Navia! Is this a weird new form of greeting in your part of
the world?

>-0 is minus zero is zero!

Not in ones-complement. You /do/ realise that ones-complement has two
zeros, don't you?

>And that is a bit pattern of all ZEROS!

Zero is all bits zero. We can agree about that
Minus zero is therefore the complement of that.
ie all-bits-one.
This is the definition of ones-complement.

Of course, its extremely possible that the Maths depts of several
universities are wrong.

>~0 is a bit pattern of all ones!

Possibly.
--
Mark McIntyre

"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are,
by definition, not smart enough to debug it."
--Brian Kernighan

Mark McIntyre, Nov 18, 2007
12. peteGuest

Mark McIntyre wrote:
>
> On Sun, 18 Nov 2007 17:55:21 +0100, in comp.lang.c , jacob navia
> <> wrote:
>
> >Mark McIntyre wrote:
> >> ?Harald van D?k wrote:
> >>> -0 is positive zero,
> >>> and when the subtraction generates that, there
> >>> are no extra problems.
> >>
> >> You sure? The bitpattern of -0 is all-ones I think.
> >>

> >
> >You think?

I don't see in this thread anywhere
if it has been established
that one's complement representation
is any more relevant than sign and magnitude.

> >-0 is minus zero is zero!

>
> Not in ones-complement.

It depends on what you mean.

It is unspecified whether a negative zero
becomes a normal zero when stored in an object.

--
pete

pete, Nov 18, 2007
13. Ben BacarisseGuest

Mark McIntyre <> writes:

> On Sun, 18 Nov 2007 17:55:21 +0100, in comp.lang.c , jacob navia
> <> wrote:
>
>>Mark McIntyre wrote:
>>> ?Harald van D?k wrote:
>>>> -0 is positive zero, and when the subtraction generates that, there
>>>> are no extra problems.
>>>
>>> You sure? The bitpattern of -0 is all-ones I think.
>>>

>>
>>You think?

>
> I certainly did.
>
>>-0 is minus zero is zero!

>
> Not in ones-complement. You /do/ realise that ones-complement has two
> zeros, don't you?

[Nit: *may* have two zeros. As far as C is concerned, the "other zero"
may be trap representation which is not "negative zero".]

I hope you see that you may be talking at cross-purposes. Both the
notation "-0" and the phrase "minus zero" are ambiguous to the extent
that without a little clarification you could go on arguing forever
over nothing.

The standard uses the term "negative zero". In a C newsgroup it is
reasonable to interpret -0 as a C expression. It is also reasonable
(though ambiguous) to voice that as "minus zero". Thus what Jacob
Navia wrote is not wrong.

--
Ben.

Ben Bacarisse, Nov 18, 2007
14. RichardGuest

Mark McIntyre <> writes:

> On Sun, 18 Nov 2007 17:55:21 +0100, in comp.lang.c , jacob navia
> <> wrote:
>
>>Mark McIntyre wrote:
>>> ?Harald van D?k wrote:
>>>> -0 is positive zero, and when the subtraction generates that, there
>>>> are no extra problems.
>>>
>>> You sure? The bitpattern of -0 is all-ones I think.
>>>

>>
>>You think?

>
> I certainly did.
>
>>Gosh McIntyre!

>
> Slainte Navia! Is this a weird new form of greeting in your part of
> the world?
>
>>-0 is minus zero is zero!

>
> Not in ones-complement. You /do/ realise that ones-complement has two
> zeros, don't you?

Ones complement? I think you are missing the point. "-0" IS "minus zero"
e.g the expression. This optimizes to ... nothing.

>
>>And that is a bit pattern of all ZEROS!

>
> Zero is all bits zero. We can agree about that
> Minus zero is therefore the complement of that.
> ie all-bits-one.
> This is the definition of ones-complement.
>
> Of course, its extremely possible that the Maths depts of several
> universities are wrong.
>
>>~0 is a bit pattern of all ones!

>
> Possibly.

Richard, Nov 18, 2007

Harald van DÄ³k wrote:
> On Sun, 18 Nov 2007 13:07:55 +0000, Mark McIntyre wrote:

[...]
>> You sure? The bitpattern of -0 is all-ones I think.

>
> The bit pattern of -0 is all zeroes, since -0 is plain old zero. The bit

It appears to me, you talk about different things, or I might be rather
confused. As seen by the translator, -0 is unitary zero, which has
little to do with negative zero.

On a 1-complement machine, negative zero would have bit pattern ~0, but
on a sign- and magnitude machine, the MSB is 1, while the rest of the
bits would be 0.

bool is_negative_zero(int d)
{
if (d == 0)
{ /* zero & ~0 */
/* 1-complement -0: 1111...1 & 1111...1 = 1 */
/* 1-complement 0: 0000...0 & 1111...1 = 0 */
/* sign/magnitude -0:1000...0 & 1111...1 = 1000...0 */
/* sign/magnitude 0:0000...0 & 1111...1 = 0 */
if (d & ~0)
return true;
}
return false;
}

> pattern of ~0 is all ones, and that is allowed to be negative zero. You
> can't create negative zero except by bit manipulation; it's simply not
> allowed, even if it would make sense for the processor.

Right, *if* negative zero is supported by the implementation, then a
negative zero can only be created as a result of bitwise op.

--
Tor < | tr i-za-h a-z>

16. Peter NilssonGuest

"" wrote:
> The following function determines the maximum of two
> integers.

Not portably. What is it meant to do that (a < b) doesn't?

> It works on my machine.

Which has little to do with the price of eggs.

>
> If (a[0] - a[1]) is negative,

Consider INT_MAX - INT_MIN.

> what's the first bit of:
> (unsigned)(a[0] - a[1])? Is it 0 or 1?
>
> #include <limits.h>
>
> 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)];

Tip: If you're using sizeof and CHAR_BIT, then there's a
99.9999% chance you've already got it wrong.

> }

--
Peter

Peter Nilsson, Nov 18, 2007
17. Joe WrightGuest

wrote:
> 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?
>
>
> #include <limits.h>
>
> 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)];
> }
>
>
> Thank you for your time

Why so complicated?

#define MAX(A,B) ((A) > (B) ? (A) : (B))

--
Joe Wright
"Everything should be made as simple as possible, but not simpler."
--- Albert Einstein ---

Joe Wright, Nov 18, 2007
18. peteGuest

Peter Nilsson wrote:
>
> "" wrote:
> > The following function determines the maximum of two
> > integers.

>
> Not portably. What is it meant to do that (a < b) doesn't?
>
> > It works on my machine.

>
> Which has little to do with the price of eggs.
>
> >
> > If (a[0] - a[1]) is negative,

>
> Consider INT_MAX - INT_MIN.
>
> > what's the first bit of:
> > (unsigned)(a[0] - a[1])? Is it 0 or 1?
> >
> > #include <limits.h>
> >
> > 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)];

>
> Tip: If you're using sizeof and CHAR_BIT, then there's a
> 99.9999% chance you've already got it wrong.

It's OK for an itoa buffer.

char itoa_buff[(sizeof(int) * CHAR_BIT - 1) / 3 + 2] = "";
char utoa_buff[(sizeof(int) * CHAR_BIT ) / 3 + 1] = "";

--
pete

pete, Nov 19, 2007
19. CBFalconerGuest

Joe Wright wrote:
>

.... snip ...
>
> Why so complicated?
>
> #define MAX(A,B) ((A) > (B) ? (A) : (B))

...
m = MAX(a++, b--);

fouls. Now what?

--
Chuck F (cbfalconer at maineline dot net)
<http://cbfalconer.home.att.net>

--
Posted via a free Usenet account from http://www.teranews.com

CBFalconer, Nov 19, 2007
20. Keith ThompsonGuest

CBFalconer wrote:
> Joe Wright wrote:
> ... snip ...
>> Why so complicated?
>>
>> #define MAX(A,B) ((A) > (B) ? (A) : (B))

>
> ...
> m = MAX(a++, b--);
>
> fouls. Now what?

Now you know better than to invoke a macro with arguments that have side
effects. (Fortunately, the name is all-caps, which is a strong hint.)

How often would you really want to compute the maximum of a++ and b--?

--
Keith Thompson (The_Other_Keith) <>
Looking for software development work in the San Diego area.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"

Keith Thompson, Nov 19, 2007