How to do adding/subtracting with bitwise operators

Started by
43 comments, last by MrEvil 19 years, 7 months ago
Continuing weirdness, cool division (and also cool subtraction)
//subtraction is needed for division. Of course i can do cool subtraction via cool addition,but it's...inelegantint coolsub(int a,int b){	int c,result, tmp;	c=((~a)&b)<<1;	result=a^b;	while(c!=0){		tmp=result^c;		c=((~result)&c)<<1;		result=tmp;	};	return result;};const high_bit=( ~((unsigned int)(0)) ^ (~((unsigned int)(0))>>1) );int cooldivide(int a,int b){	if(b==0)return 0;//division by zero. What i should return....	if(b==1)return a;	int s=0;	//note that general >,<,<=,>= do subtraction :)      	if(a&high_bit){a=coolsub(0,a);s=1;}	if(b&high_bit){b=coolsub(0,b);s^=1;}	int c,d,m=1,r=0;	c=b;	d=c<<1;	while(d>c){		c=d;		d<<=1;		m<<=1;	}	int e=a;	int k=0;	do{		k=coolsub(e,c);		if((k&high_bit)==0){e=k;r+=m;};		m>>=1;		c>>=1;		}while((m!=0)&&(e!=0));	if(s){return coolsub(0,r);}else{return r;}}

and comparasion:
a<b
coolsub(a,b)&high_bit
a<=b
(coolsub(b,a)&high_bit)==0
> and >= is the same.

edit:as about subtraction via addition,

i'd rather do it in that way:
int coolsub2(int a,int b){
return cooladd(cooladd(~a,~b),2);
};
,rather than using coolmultiply to multiply with (~0) :).

And important thing, coolmultiply need simple fix to work with signed numbers, same as one used in cooldiv.

[Edited by - Dmytry on September 2, 2004 6:46:30 AM]
Advertisement
I have already written your cooladd,coolmultiply, etc. functions in INTERCAL and TriINTERCAL (which is a super-obfuscated and quirky language which should never have been born - Blame Eric S. Raymond). Did the interviewer specify a language to write in?

In INTERCAL or any dialect thereof(http://www.catb.org/~esr/intercal), the program becomes:

(100) DO (1020) NEXT
DO RESUME #1

Which increments the 16-bit variable .1. Note the lack of equals signs. It also has the advantage of working in binary, ternary, all the way up to base 7.


As an extra, memory-guzzling idea, I thought also you could use Standard Template Library containers and the functional algorithms.
You could create a linked list and use the functional library to fill it with a numeric sequence, starting at 0, ending at 2^(sizeof(unsigned int)*8)-1, so that list[x] == x for all possible unsigned x values.
Get an iterator to list[x], increment the iterator, and you have &list[x+1], which should equal x+1.

I dont know how you increment the iterator without using +'s , but i'm sure there's a way. In any case, the INTERCAL routine was the main addition to this thread, useless though it may be. :)
Quote:Original post by Dmytry
And important thing, coolmultiply need simple fix to work with signed numbers, same as one used in cooldiv.


Actually, my coolmultiply works for signed numbers too, I have tested it. Or did you find some specific numbers it fails for?
oh,my bad... it's because i know processor have different operations for signed multiply and unsigned ,and have never thinked about it.
In fact it's just only because result of processor's 32bit multiply is 64-bit and there's real difference.
Quote:
Melekor:
Actually, my coolmultiply works for signed numbers too, I have tested it. Or did you find some specific numbers it fails for?


Yes, my intercal routine does the same thing - it was written for unsigned integers, but it works for signed numbers in 2's complement format and the ternary version works in unsigned form, 3's complement form and even balanced ternary..

This topic is closed to new replies.

Advertisement