Google Mail Calendar Documents Reader Web more »
Recently Visited Groups | Help | Sign in
Google Groups Home
ternary-free way of implementing max(q,r)
There are currently too many topics in this group that display first. To make this topic appear first, remove this option from another topic.
There was an error processing your request. Please try again.
flag
  10 messages - Collapse all  -  Translate all to Translated (View all originals)
The group you are posting to is a Usenet group. Messages posted to this group will make your email address visible to anyone on the Internet.
Your reply message has not been sent.
Your post was successful
 
From:
To:
Cc:
Follow-up To:
Add Cc | Add Follow-up to | Edit Subject
Subject:
Validation:
For verification purposes please type the characters you see in the picture below or the numbers you hear by clicking the accessibility icon. Listen and type the numbers that you hear
 
Andrey Vul  
View profile   Translate to Translated (View Original)
 More options 7 Nov, 20:46
Newsgroups: comp.lang.c
From: Andrey Vul <andrey....@gmail.com>
Date: Sat, 7 Nov 2009 12:46:41 -0800 (PST)
Local: Sat 7 Nov 2009 20:46
Subject: ternary-free way of implementing max(q,r)
Here is a ternary-free way of implementing max(q,r)
int max(int q,int r) {return ((q>r)*q)+((q<=r)*r) ;}

It works thanks to 6.5.8 .
Any comments?


    Reply    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message, you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Andrey Vul  
View profile   Translate to Translated (View Original)
 More options 7 Nov, 20:51
Newsgroups: comp.lang.c
From: Andrey Vul <andrey....@gmail.com>
Date: Sat, 7 Nov 2009 12:51:40 -0800 (PST)
Local: Sat 7 Nov 2009 20:51
Subject: Re: ternary-free way of implementing max(q,r)
There is also a branch-free way, but it requires limits.h

(q + r + ((q + r) & INT_MAX))>>1


    Reply    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message, you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Eric Sosman  
View profile   Translate to Translated (View Original)
 More options 7 Nov, 22:31
Newsgroups: comp.lang.c
From: Eric Sosman <esos...@ieee-dot-org.invalid>
Date: Sat, 07 Nov 2009 17:31:59 -0500
Local: Sat 7 Nov 2009 22:31
Subject: Re: ternary-free way of implementing max(q,r)

Andrey Vul wrote:
> There is also a branch-free way, but it requires limits.h

> (q + r + ((q + r) & INT_MAX))>>1

     Obviously broken on overflow, but also broken on some
perfectly ordinary cases.  q==1, r==-1, for example.

--
Eric Sosman
esos...@ieee-dot-org.invalid


    Reply    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message, you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Ike Naar  
View profile   Translate to Translated (View Original)
 More options 7 Nov, 22:44
Newsgroups: comp.lang.c
From: i...@localhost.claranet.nl (Ike Naar)
Date: Sat, 7 Nov 2009 22:44:21 +0000 (UTC)
Local: Sat 7 Nov 2009 22:44
Subject: Re: ternary-free way of implementing max(q,r)
In article <80f0ea41-16e6-4744-ad1e-c756af0a2...@k17g2000yqb.googlegroups.com>,
Andrey Vul  <andrey....@gmail.com> wrote:

>There is also a branch-free way, but it requires limits.h

>(q + r + ((q + r) & INT_MAX))>>1

That does not work (try q = r = 1).
Perhaps you're thinking of (q + r + abs(q - r)) / 2 ?

    Reply    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message, you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Andrey Vul  
View profile   Translate to Translated (View Original)
 More options 7 Nov, 22:46
Newsgroups: comp.lang.c
From: Andrey Vul <andrey....@gmail.com>
Date: Sat, 7 Nov 2009 14:46:15 -0800 (PST)
Local: Sat 7 Nov 2009 22:46
Subject: Re: ternary-free way of implementing max(q,r)
On Nov 7, 5:31 pm, Eric Sosman <esos...@ieee-dot-org.invalid> wrote:
> Andrey Vul wrote:
> > There is also a branch-free way, but it requires limits.h

> > (q + r + ((q - r) & INT_MAX))>>1

>      Obviously broken on overflow, but also broken on some
> perfectly ordinary cases.  q==1, r==-1, for example.

Sorry, mixed + and -.

Is there a non-overflowing way to do abs() as a one-liner?

Branch-free is from math class:
max(a,b) = $ \{ a + b + | a - b|} \over {2} $


    Reply    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message, you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Flash Gordon  
View profile   Translate to Translated (View Original)
 More options 7 Nov, 22:12
Newsgroups: comp.lang.c
From: Flash Gordon <s...@spam.causeway.com>
Date: Sat, 07 Nov 2009 22:12:19 +0000
Local: Sat 7 Nov 2009 22:12
Subject: Re: ternary-free way of implementing max(q,r)

Andrey Vul wrote:
> There is also a branch-free way, but it requires limits.h

> (q + r + ((q + r) & INT_MAX))>>1

I don't see that requiring limits.h is a problem. However, this solution
can overflow which is undefined behaviour (i.e. anything can happen) and
implementation defined behaviour if q and r are negative, so there is no
guarantee it will work.
--
Flash Gordon

    Reply    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message, you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Beej Jorgensen  
View profile   Translate to Translated (View Original)
 More options 7 Nov, 23:20
Newsgroups: comp.lang.c
From: Beej Jorgensen <b...@beej.us>
Date: Sat, 7 Nov 2009 23:20:58 +0000 (UTC)
Local: Sat 7 Nov 2009 23:20
Subject: Re: ternary-free way of implementing max(q,r)
Andrey Vul  <andrey....@gmail.com> wrote:

>There is also a branch-free way, but it requires limits.h

>(q + r + ((q + r) & INT_MAX))>>1

Plus it suffers if the addition overflows.

I like the conditional variant because it takes me back to the good old
days, where -1 was true in C64 BASIC. :)

Now, to go OT:

Some timings, FWIW, with gcc 4.4.2 -O2, AMD Athlon64, 100 million
iterations (calculate the total of the maximum of two pseudo-random
numbers), runtime affected by the loading whims of my PC:

   code                                        runtime
   ------------------------------------------  -------
   #define MYMAX1(a,b) ((a)<(b)?(b):(a))       3.311
   if (a < b) return b; else return a;         3.340
   return ((a>b)*a)+((a<=b)*b);                3.328
   return (a + b + ((a + b) & INT_MAX))>>1;    3.339

The first two generated identical assembly, unsurprisingly.  They make
use of the "conditional move" instruction, so the assembly for computing
the max is basically:

  CMP a,b
  CMOV a,b

None of the assembly produced in any of the four tests had any explicit
branches--it was all compares and conditional instructions.

I think the only lesson to be drawn from the timings is, "Sometimes
optimizations don't do what you think they'll do."  When it comes to
little things like this, I'm a big fan of just coding it straight and
then optimizing if its required.

Perhaps on a RISCier machine (one without Intel's DOIT instruction ;) ),
the differences would be... existent.

-Beej


    Reply    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message, you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Kalle Olavi Niemitalo  
View profile   Translate to Translated (View Original)
 More options 7 Nov, 22:59
Newsgroups: comp.lang.c
From: Kalle Olavi Niemitalo <k...@iki.fi>
Date: Sun, 08 Nov 2009 00:59:41 +0200
Local: Sat 7 Nov 2009 22:59
Subject: Re: ternary-free way of implementing max(q,r)

Andrey Vul <andrey....@gmail.com> writes:
> There is also a branch-free way, but it requires limits.h

> (q + r + ((q + r) & INT_MAX))>>1

With q==2, r==4, and INT_MAX==32767, that expression seems
to evaluate to 6, although the correct max(2,4) would be 4.

    Reply    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message, you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Kalle Olavi Niemitalo  
View profile   Translate to Translated (View Original)
 More options 7 Nov, 23:12
Newsgroups: comp.lang.c
From: Kalle Olavi Niemitalo <k...@iki.fi>
Date: Sun, 08 Nov 2009 01:12:19 +0200
Local: Sat 7 Nov 2009 23:12
Subject: Re: ternary-free way of implementing max(q,r)

Andrey Vul <andrey....@gmail.com> writes:
> Here is a ternary-free way of implementing max(q,r)
> int max(int q,int r) {return ((q>r)*q)+((q<=r)*r) ;}

Your C expression is more difficult for me to understand than
(q > r) ? q : r, and I doubt the generated code is faster either.
The ?: version also works with pointers (to elements of the same
array), which cannot be multiplied.

This kind of Boolean*integer multiplication made some sense in
old BASIC programs, but I don't see a purpose for it in C, where
we have ?: available.  If you were implementing your own C
compiler and hadn't implemented ?: in the parser yet, I think
it would be rather simple to implement max(q,r) as a built-in
function.  (A standard-conforming compiler would have to call it
e.g. __max but a compiler without ?: wouldn't conform anyway.)


    Reply    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message, you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
David Thompson  
View profile   Translate to Translated (View Original)
 More options 19 Nov, 03:24
Newsgroups: comp.lang.c
From: David Thompson <dave.thomps...@verizon.net>
Date: Wed, 18 Nov 2009 22:24:04 -0500
Local: Thurs 19 Nov 2009 03:24
Subject: Re: ternary-free way of implementing max(q,r)
On Sat, 7 Nov 2009 14:46:15 -0800 (PST), Andrey Vul

<andrey....@gmail.com> wrote:
> On Nov 7, 5:31 pm, Eric Sosman <esos...@ieee-dot-org.invalid> wrote:
> > Andrey Vul wrote:
> > > There is also a branch-free way, but it requires limits.h

> > > (q + r + ((q - r) & INT_MAX))>>1

> >      Obviously broken on overflow, but also broken on some
> > perfectly ordinary cases.  q==1, r==-1, for example.
> Sorry, mixed + and -.

Only on sign&magnitude machines, which no longer exist in any
practical sense. Still broken on everything else. See below.

> Is there a non-overflowing way to do abs() as a one-liner?

> Branch-free is from math class:
> max(a,b) = $ \{ a + b + | a - b|} \over {2} $

With abs this works. But there is no standard computational
(conceptually branchless) operation that directly does abs.

What you can do is a + (a<b)*(b-a), and on *most* 2sC machines,
although not required by the standard, in the absence of overflow
this can be done by: a + -((a-b)>>INTbits) * (b-a)
or slightly 'simpler': a + ( (a-b)>>INTbits & (b-a) )
where usually INTbits is sizeof(INT)*CHAR_BIT-1
(unless padding bits are used, rarely if ever).

For abs start with a*( 1-(a<0)*2 ) and proceed similarly.

That said, I concur with the sentiment elsethread to just write the
ternary operator and let the compiler generate the code; if it screws
up such a basic thing, you need a better compiler anyway.


    Reply    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message, you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
End of messages
« Back to Discussions « Newer topic     Older topic »

Create a group - Google Groups - Google Home - Terms of Service - Privacy Policy
©2009 Google