On 12ÔÂ9ÈÕ, ÉÏÎç12ʱ24·Ö, Flash Gordon <s...@flash-gordon.me.uk> wrote:
> James Fang wrote, On 08/12/07 13:33:
>
>
>
> > On 12ÔÂ8ÈÕ, ÏÂÎç7ʱ22·Ö, Flash Gordon <s...@flash-gordon.me.uk> wrote:
> >> James Fang wrote, On 08/12/07 04:23:
>
> >>> On Dec 8, 12:20 pm, James Fang <fangshang...@gmail.com> wrote:
> >>>> On Dec 7, 1:33 pm, aark...@gmail.com wrote:
> >>>>> Hi all,
> >>>>> The following question is asked frequently in interviews
> >>>>> How to find the greatest of 2 numbers without using relational
> >>>>> operators ?
> >>>>> the solution i have seen is
> >>>>> ( a+b + abs(a-b) ) /2 ;
> >>>>> is there any better solution than this ....?????
> >>>> In your solution there's an overflow issue.
> >>>> Actually there's a simpler solution: you can use an array, and use the
> >>>> array index istead of the relational operators.
> >>>> int max(int a,int b)
> >>>> {
> >>>> int array[2];
> >>>> array[0]=a;
> >>>> array[1]=b;
> >>>> return array[(a-b)&0x80000000];
> >>>> }
> >> Did you actually test this piece of rubbish? When I try it I always get
> >> the value of a. I'm really not sure how it is giving me that since the
> >> code is so broken. Just to show you how bad I've added a bit of
> >> diagnostic and here it is...
>
> >> markg@brenda:~$ cat t.c
> >> #include<stdio.h>
>
> >> int max(int a,int b)
> >> {
> >> int array[2];
> >> array[0]=a;
> >> array[1]=b;
> >> printf("%d\n",(a-b)&0x80000000);
> >> return array[(a-b)&0x80000000];
>
> >> }
>
> >> int main(void)
> >> {
> >> printf("%d\n",max(1,2));
> >> return 0;}
>
> >> markg@brenda:~$ gcc -ansi -Wall -Wextra -O t.c
> >> markg@brenda:~$ ./a.out
> >> -2147483648
> >> 1
> >> markg@brenda:~$
>
> >> Obviously the index is just a little outside the array.
>
> >>>> also, you can make use of the C system stack
> >> C does not have a system stack. Your implementation might, but equally
> >> well it might not work as you expect.
>
> >>>> to get rid of extra
> >>>> memory space:
> >>>> int max(int a,int b)
> >>>> {
> >>>> // in C standard, the function parameters are pushed from right to
> >>>> left.
> >> Or they are passed in registers (if you take the address then obviously
> >> it has to allocate a memory location), or the stack might not grow in
> >> the direction you expect, or the parameters might be pushed left to right...
>
> >>>> // so integer b is stored in high address.
> >>>> return array *(&a+((a-b)&0x80000000>>31));
> >> int might not be 32 bits. It invokes undefined behaviour if you take a
> >> pointer to a, add 1 to it, and dereference it.
>
> >>>> }
> >>> Sorry, I've made a mistake, the second implementation should be:
> >>> int max(int a,int b)
> >>> {
> >>> // in C standard, the function parameters are pushed from right to
> >>> left.
> >>> // so integer b is stored in high address.
> >>> return *(&a+((a-b)&0x80000000>>31));
> >>> }
> >> No, the second implementation should be erased not corrected, and anyone
> >> who thinks it is valid needs to learn C. The first could be corrected as
> >> an intellectual exercise, but should never be used in real life.
> >> --
> >> Flash Gordon
>
> > Actually, I just missed one shift operation in the max function
> > because the code was written in a hurry in the bbs reply, attached
> > below is the corrected function int max(int,int).
>
> No, you have several other errors. With assume int is 32 bits as I
> already stated, your code will invoke undefined behaviour due to
> overflow with some values. It may well have other problems, your second
> example certainly does.
>
> > My code is directly written in the bbs reply, the purpose of my code
>
> I have no idea what you mean by bbs.
>
> > is to illustrate new idea and algorithm, rather than help sb directly
> > do copy&paste job. The entire execution code is pasted below, it was
> > compiled with gcc and had basic functionality test on win32 system.
>
> Specific implementations are not relevant.
>
> > #include <stdio.h>
>
> > int max(int a,int b)
> > {
> > int array[2];
> > array[0]=a;
> > array[1]=b;
> > return array[((a-b)&0x80000000)>>31];
> > }
>
> > int main()
> > {
> > printf("%d\n",max(-1,100));
> > printf("%d\n",max(10000,100));
> > printf("%d\n",max(99,99));
>
> #include <limits.h>
> printf("%d\n",max(INT_MIN,INT_MAX);
>
> I get the value of INT_MIN printed which is just a little incorrect.
>
> > getchar();
> > }
>
> Basically the only sensible answer is that it is a stupid question.
> --
> Flash Gordon
You are right, detection of arithmetical overflow with portable
solution should be a problem.
The following code can handle the arithmetical overflow, but it still
assumes that the sign bit is the high bit, which might be non-portable
on some CPUs.
In fact,these processor specific differences should be concealed by
the C compiler,right?
int get_max(int a,int b)
{
long long divisor = (long long)a-(long long)b;
int array[2];
array[0]=a;
array[1]=b;
return array[( divisor & (ULLONG_MAX/2+1U) ) >> ((sizeof(long
long)*

-1)];
}
Thanks and Regards,
James