The old Google Groups will be going away soon, but your browser is incompatible with the new version.
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)
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)
Lines: 112
Message-ID: <10932293.3495.1335786981872.JavaMail.geo-discussion-forums@vbbfr18>
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)
NNTP-Posting-Date: Mon, 30 Apr 2012 12:13:15 +0000 (UTC)
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)

(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

(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
>         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.
```