C Puzzles

yet another place for C puzzles

Friday, July 22, 2005

 

MAX of two numbers without relational operators.


int max(int a,int b)
{
int g=0 ;

!a && b && ( ((b+1)/b ) && (g = b) || (g=a));
!b && a && ( ((a+1)/a ) && (g = a) || (g=b));

(!(!a || !b)) &&
( (( ( !((b+1)/b) && (!( a/b) ) )
|| ( ((a+1)/a) && (a/b) )
) && (g=a))
|| (g=b)
);
return g;
}


logic is here:

int max(int a,int b)
{
int g=0 ;
if (a == 0 and b != 0 ) {
if ( b is +ve)
b is greatest
else
a is greatest
}
if (b == 0 and a != 0 ) {
if ( a is +ve)
a is greatest
else
b is greatest
}
if ( a and b are non-zero ) {
if( [b is negative and b is magnitudely high]
or [a is positive and a is magnitudely high] )
then
a is greatest
otherwise
b is greatest
}
return the greatest value;
}

NOTE: this program will not work for a single value LONG_MAX;
Unit-test and other ideas are added as comments

Comments:
Unit-test
----------
spyglass: $cat my_version2.c


int max(int a,int b)
{
int g=0 ;

!a && b && ( ((b+1)/b ) && (g = b) || (g=a));
!b && a && ( ((a+1)/a ) && (g = a) || (g=b));

(!(!a || !b)) &&
( (( ( !((b+1)/b) && (!( a/b) ) )
|| ( ((a+1)/a) && (a/b) )
) && (g=a))
|| (g=b)
) ;
return g;
}

int main()
{
int a,b;
int g;
int i=15; // max no of expected data

printf("Enter two numbers:");
scanf("%d %d", &a , &b );
while( --i ){
g = max(a,b);
printf("greatest = %d ,small =%d \n", g, a+b-g );

printf("Enter two numbers:");
scanf("%d %d", &a , &b );
}
}

spyglass: $gcc my_version2.c
spyglass: $cat test_data.txt
10 2
2 10
-2 10
10 -2
-2 -10
-10 -2
-10 2
2 -10
0 0
0 10
10 0
-10 0
0 -10


spyglass: $./a.out < test_data.txt
Enter two numbers:greatest = 10 ,small =2
Enter two numbers:greatest = 10 ,small =2
Enter two numbers:greatest = 10 ,small =-2
Enter two numbers:greatest = 10 ,small =-2
Enter two numbers:greatest = -2 ,small =-10
Enter two numbers:greatest = -2 ,small =-10
Enter two numbers:greatest = 2 ,small =-10
Enter two numbers:greatest = 2 ,small =-10
Enter two numbers:greatest = 0 ,small =0
Enter two numbers:greatest = 10 ,small =0
Enter two numbers:greatest = 10 ,small =0
Enter two numbers:greatest = 0 ,small =-10
Enter two numbers:greatest = 0 ,small =-10
Enter two numbers:greatest = 0 ,small =-10 <<<< ignore the tail
Enter two numbers:spyglass: $
spyglass: $
 
Other-ideas :
____________________________

void compare (int a, int b)
{
int diff, msb;

msb = 1 << (sizeof(int)*8 - 1);

if ((a & msb) && !(b &msb)) /* a is negative and not b */
return b;
else if ((b & msb) && !(a &msb)) /* b is negative and not a */
return a;

/* a and b are of same sign */
diff = a-b;
if (!diff || !(diff & msb)) /* a==b and a > b */
return a;
return b;
}


Regards,
Arul Kumar C
_________________________________

void compare (int a, int b)
{
int i, aset, bset;

if (!(a ^ b))
printf("a=b\n");
else { /* either a < b or a > b */
i = 31;
while (i ^ -1) { /* while i != -1 */
aset = bset = 0;
if (a & (1 << i)) /* ith bit from left is set in a */
aset = 1;
if (b & (1 << i)) /* ith bit from left is set in b */
bset = 1;
if (!(aset ^ bset)) { /* bits in both a & b set or both are not set */
i--; continue;
}
else { /* there is a mismatch */
if (!(i ^ 31)) { /* i is 31, take care of negative nos */
if (aset) printf("a < b\n");
else printf("a > b\n");
}
else {
if (aset) printf("a > b\n");
else printf("a < b\n");
}
return;
}
}
}
}


int main()
{
int a,b;
printf("Enter a:");
scanf("%d", &a);
printf("Enter b:");
scanf("%d", &b);
compare(a,b);
}

Thanks,
Anand
 
Hi Vinod,

I forgot to add comments.

Is it a implementation independent code?Especially, checking the MSB for -ve values ?Page 36 in K&R (2.2 Data Types and Sizes) says about 'char'.he is saying that it is machine-dependent.Am not sure about 'int'.

if x is a large +ve and y is a large -ve, it might result in overflow.
 
yes, checking a MSB depends on compilers also. ex:- notation of compiler whether it is a little indian and big indian etc.,

so i am thinking of this solution

int max_two(int i, int j)
{
int temp = i - j;
if(!temp) return i; // if both are equal
return (((temp+1)/ temp) ? i : j ); // if not equal
}
 
Post a Comment

Subscribe to Post Comments [Atom]





<< Home

Archives

July 2005   August 2005   October 2005   December 2005   March 2006   June 2006   July 2006   December 2006   February 2007   June 2007   March 2010   May 2010  

This page is powered by Blogger. Isn't yours?

Subscribe to Posts [Atom]