Message from discussion
Determine if two integers have different sign
Received: by 10.68.223.40 with SMTP id qr8mr3979809pbc.0.1335787995579;
Mon, 30 Apr 2012 05:13:15 -0700 (PDT)
Path: r9ni115692pbh.0!nntp.google.com!news2.google.com!postnews.google.com!glegroupsg2000goo.googlegroups.com!not-for-mail
From: thomas.mer...@gmx.at
Newsgroups: gnu.gcc.help
Subject: Re: Determine if two integers have different sign
Date: Mon, 30 Apr 2012 04:56:21 -0700 (PDT)
Organization: http://groups.google.com
Lines: 112
Message-ID: <10932293.3495.1335786981872.JavaMail.geo-discussion-forums@vbbfr18>
References: <5825989.186.1335775579944.JavaMail.geo-discussion-forums@ynlp3> <QN6dnfZ0JPK89QPSnZ2dnUVZ_vadnZ2d@supernews.com>
NNTP-Posting-Host: 84.112.82.23
Mime-Version: 1.0
X-Trace: posting.google.com 1335787995 17252 127.0.0.1 (30 Apr 2012 12:13:15 GMT)
X-Complaints-To: groups-abuse@google.com
NNTP-Posting-Date: Mon, 30 Apr 2012 12:13:15 +0000 (UTC)
In-Reply-To: <QN6dnfZ0JPK89QPSnZ2dnUVZ_vadnZ2d@supernews.com>
Complaints-To: groups-abuse@google.com
Injection-Info: glegroupsg2000goo.googlegroups.com; posting-host=84.112.82.23; posting-account=269_QwoAAADSifhJt6OVa6bEjZR2ZMUB
User-Agent: G2/1.0
Content-Type: text/plain; charset=ISO-8859-1
On Monday, April 30, 2012 12:23:29 PM UTC+2, Andrew Haley wrote:
> tm wrote:
> > I use the following condition, to determine, if a and b have
> > different signs:
> >
> > (a>0&&b<0)||(a<0&&b>0)
> >
> > Cases were a=0 or b=0 hold are handled separate. When twos
> > complement integers are used, something like
> >
> > (a^b)<0
> >
> > would do the same. The second solution is probably faster (but maybe
> > this assumption is wrong).
> >
> > Can I assume that a C compiler like gcc does this optimization?
>
> No, unfortunately.
>
> > The code above is generated in the backend of the Seed7 compiler.
> > The type of integer representation is known, so the Seed7 compiler
> > could decide, which code should be generated.
> >
> > Does it pay off, to do such low level optimizations, or is it better
> > to leave them to the C compiler?
>
> There isn't any need to depend on two's-completement arithmetic.
> I would simply do this:
>
> int div3(int a, int b) {
> int sign = (a < 0) ^ (b < 0);
> int c = a % b;
> if (sign && c != 0)
> return c + b;
> else
> return c;
> }
I was not aware of the possibility to use:
(a<0)^(b<0)
What about:
(a<0)!=(b<0)
Is it faster or slower?
As I said, the Seed7 compiler knows, which integer representation is
used. So it could use
(a^b)<0
instead of
(a<0)^(b<0)
when two's complement representation is used. Do you think that
(a^b)<0 is faster?
Btw. The Seed7 compiler does not use a function like div3. Instead
it produces inline code. The Seed7 source code:
modResult := dividend mod divisor;
is currently translated to (a little bit simplified):
{
inttype tmp_a;
inttype tmp_b;
inttype tmp_c;
o_1017_modResult=
(tmp_a=o_1015_dividend,
tmp_b=o_1016_divisor,
tmp_c=tmp_a%tmp_b,
((tmp_a>0&&tmp_b<0)||(tmp_a<0&&tmp_b>0))&&
tmp_c!=0?tmp_c+tmp_b:tmp_c);
}
> which generates
>
> movl %edi, %edx
> movl %edi, %eax
> sarl $31, %edx
> idivl %esi
> xorl %esi, %edi
> jns .L16
> testl %edx, %edx
> setne %al
> addl %edx, %esi
> testb %al, %al
> cmovne %esi, %edx
> .L16:
> movl %edx, %eax
> ret
>
> There is are some other forms that generate better code for special
> cases, in particular when it is known a priori that the divisor is
> positive. However, I don't think you'll beat this for the general
> case.
The Seed7 compiler generates special code when dividend or divisor
(or both :-) ) are known at compiler time.
Greetings Thomas Mertes
--
Seed7 Homepage: http://seed7.sourceforge.net
Seed7 - The extensible programming language: User defined statements
and operators, abstract data types, templates without special
syntax, OO with interfaces and multiple dispatch, statically typed,
interpreted or compiled, portable, runs under linux/unix/windows.