darren@revcan.UUCP (Darren Morbey) (04/02/91)
I've noticed in my writing C code that there is no such operator as ^^ (which would be to ^ as || is to |). I feel in this case I *have* to write a macro for this *nonexistent* operator (you may recall I wrote #define XOR(a,b) ((a)^(b)) ). However... The Pascal xor operator is <>, which follows since it has a Boolean type on which its and & or operators can (and only will) operate. Since C uses any non-zero value as 'true', it seems the only reason to include && and || to avoid trouble with & and |. The problem is, there is no ^^ to avoid trouble with ^. I would like to use one of the following three macros, but each has its own particular problems. I would appreciate any advice on which one should be used. I would like it to operate like && and ||. 1. #define XOR(a,b) ( ( !(a) && (b) ) || ( (a) && !(b) ) ) - Althought this is straight from the definition of XOR ( as (NOT A AND B) OR (A AND NOT B) ) it must evaluate a and b *twice* (obvious loss of flexibility) 2. #define XOR(a,b) ( !(a) != !(b) ) - This is meant to overcome C's acceptance of multiple TRUEs ( unlike Pascal's single TRUE value ). This relies on the following statements being true: ( 0 == 0L ) (since a and b may yield different sized int's) ( !0 == !(0L) ) ( !(0L) == !('\0') ) (which may happen!) etc. Can such expressions be *guaranteed* true? 3. #define XOR(a,b) ( (a) ? !(b) : (b) ) /* my favourite. */ - This relies simply on one thing: in the conditional expression, do *both* !(b) and (b) get evaluated, regardless of which is returned? Or is only the value to be returned evaluated. (Final note: This *is* meant to be *portable*. Be very careful.) [ Darren Morby +1 613 957 9281 {uunet|lsuc|fts1}!revcan!darren ] [ Revenue Canada Taxation, 3052-400 Cumberland St, Ottawa,ONT K1A 0L8 ] (included for those who wish to send mail, call me, or send any lynch) (mobs you can hire. :-) )
ckp@grebyn.com (Checkpoint Technologies) (04/03/91)
In article <156@revcan.UUCP> darren@revcan.UUCP (Darren Morbey) writes: >I've noticed in my writing C code that there is no such operator >as ^^ (which would be to ^ as || is to |). I feel in this case >I *have* to write a macro for this *nonexistent* operator (you may >recall I wrote #define XOR(a,b) ((a)^(b)) ). However... > >I would like to use one of the following three macros, but each has >its own particular problems. I would appreciate any advice on which >one should be used. I would like it to operate like && and ||. An ^^ operator cannot operate just like && and ||. This is because there is no possible notion of a shortcut evaluation; both sides must be evaluated in every case. I'll assume you mean for ^^ to operate on operands which are only treated as 0 or non-0, and returns either 0 or 1. >1. #define XOR(a,b) ( ( !(a) && (b) ) || ( (a) && !(b) ) ) >2. #define XOR(a,b) ( !(a) != !(b) ) >3. #define XOR(a,b) ( (a) ? !(b) : (b) ) /* my favourite. */ Here's mine: #define XOR(a,b) (((a) != 0) ^ ((b) != 0)) -- First comes the logo: C H E C K P O I N T T E C H N O L O G I E S / / ckp@grebyn.com \\ / / Then, the disclaimer: All expressed opinions are, indeed, opinions. \ / o Now for the witty part: I'm pink, therefore, I'm spam! \/
darren@revcan.UUCP (Darren Morbey) (04/03/91)
Based on some of the responses I've gotten so far, I should clarify what I would like when I say ^^. I do realize that there is no "short-circuit" evaluation (a term used repeatedly) for the Boolean xor as there is for && and ||; I didn't realize that short-circuit evaluation was the standard. What I did require was an operator, macro, or function that treated its operands as "zero" or "non-zero" as && and || do rather than the bitwise & | ^. I also would like some guarantee that both operands were evaluated *once* *and* *only* *once* (O&OO). Based on that, I do recognize that in 1. #define XOR(a,b) ( ( !(a) && (b) ) || ( (a) && !(b) ) ) I cannot guarantee that a is evaluated O&OO every time. As I mentioned, I would like to be as portable as possible, so please be careful. [ Darren Morby +1 613 957 9281 {uunet|lsuc|fts1}!revcan!darren ] [ Revenue Canada Taxation, 3052-400 Cumberland St, Ottawa,ONT K1A 0L8 ] [ "The challenge... is yours." Dick Clark. ]
barnettr@snaggle.rtp.dg.com (Richard Barnette) (04/04/91)
In article <156@revcan.UUCP> darren@revcan.UUCP (Darren Morbey) writes: >I've noticed in my writing C code that there is no such operator >as ^^ (which would be to ^ as || is to |). I feel in this case >I *have* to write a macro for this *nonexistent* operator (you may >recall I wrote #define XOR(a,b) ((a)^(b)) ). However... It can't be done. The truth or falseness of a ^ expression cannot be determined without evaluating all the operands. Note the truth tables below: A B | A XOR B A B | A AND B A B | A AND B -----+--------- -----+--------- -----+--------- F F | F F F | F F F | F F T | T F T | T F T | F T F | T T F | T T F | F T T | F T T | T T T | T Given A if F, A AND B is always F; given A is T, A OR B is always T. No such statement can be made for A XOR B; if A is T, A XOR B is NOT B; if A is F, A XOR B is B. In either case the value depends on B regardless of the value of A. ------------------------------------------------------- Richard Barnette | Data General Corporation Commercial Languages | 62 T.W. Alexander Drive (919) 248-6225 | RTP, NC 27709 ------------------------------------------------------- Inet addr: barnettr@dg-rtp.dg.com UUCP: <your 'world' string here>!mcnc!rti!dg-rtp!barnettr ------------------------------------------------------- obligatory (in)famous quote: "You wascal wabbit! Wandering wizards won't win!" - /usr/lib/sendmail /-------------------------------------------------------\ | Richard Barnette | Data General Corporation | | Commercial Languages | 62 T.W. Alexander Drive | | x 6225 | RTP, NC 27709 |
dkeisen@Gang-of-Four.Stanford.EDU (Dave Eisen) (04/04/91)
In article <157@revcan.UUCP> darren@revcan.UUCP (Darren Morbey) writes: >What I did require was an operator, macro, or function that treated >its operands as "zero" or "non-zero" as && and || do rather than >the bitwise & | ^. I also would like some guarantee that both >operands were evaluated *once* *and* *only* *once* (O&OO). Based >on that, I do recognize that in #define XOR(a,b) (!!(a) ^ !!(b)) does what you want. -- Dave Eisen 1101 San Antonio Rd. Suite 102 Mountain View, CA 94043 (415) 967-5644 dkeisen@Gang-of-Four.Stanford.EDU (for now)
jlg@cochiti.lanl.gov (Jim Giles) (04/05/91)
> [...] > It can't be done. The truth or falseness of a ^ expression > cannot be determined without evaluating all the operands. [...] What you are saying is obvious. However, the original request was for a _logical_ XOR instead of a _bit-wise_ XOR. The fact that you can't short-circuit XOR is irrelevant to that request. This is one of the problems with confounding two distinct concepts into one language feature - people soon begin to believe the two concepts are inseparable. In this case, short-circuiting and logical con/disjunction are distinct concepts that just happen to be combined into single operators. J. Giles
gwyn@smoke.brl.mil (Doug Gwyn) (04/05/91)
In article <1991Apr3.203748.3226@neon.Stanford.EDU> dkeisen@Gang-of-Four.Stanford.EDU (Dave Eisen) writes: >#define XOR(a,b) (!!(a) ^ !!(b)) or even #define XOR(a,b) (!(a)^!(b)) which is, I think, the shortest fully correct solution to this rather peculiar "requirement".
brnstnd@kramden.acf.nyu.edu (Dan Bernstein) (04/05/91)
In article <20206@lanl.gov> jlg@cochiti.lanl.gov (Jim Giles) writes: > This is one of the problems with confounding two distinct concepts > into one language feature - people soon begin to believe the two > concepts are inseparable. In this case, short-circuiting and > logical con/disjunction are distinct concepts that just happen > to be combined into single operators. What Jim fails to point out is that short-circuiting is almost entirely useless with bitwise operators---it could only make a difference if the first argument had all bits zero, and you can use (a)?(b):0 for that. Conversely, since you can always implement a non-short-circuit logical operator as (e.g.) !!(a) & !!(b), there's no reason for the language to provide any logical operators other than the short-circuit ones. This is common sense, not ``confounding.'' ---Dan
rh@smds.UUCP (Richard Harter) (04/05/91)
In article <157@revcan.UUCP>, darren@revcan.UUCP (Darren Morbey) writes: > What I did require was an operator, macro, or function that treated > its operands as "zero" or "non-zero" as && and || do rather than > the bitwise & | ^. I also would like some guarantee that both > operands were evaluated *once* *and* *only* *once* (O&OO)... Then I believe that what you want is #define XOR(a,b) ( !(a) ? (!!(b)) : (!(b)) ) which returns 1 if exactly one of the two arguments is 0 and 0 otherwise, with both arguments being evaluated exactly once. As far as I can see this is the only way to meet your requirements. I am not at all sure if it is possible to write macros for AND and OR that meet your requirements. The problem I see is this: #define AND(a,b) ( !(a) ? ((b) && 0) : !!(b) ) appears to do the trick, modulo typoes. However it occurs to me that a "clever" optimizing compiler would recognize that ((b) && 0 ) is always false and bypass the evaluation of b. Perhaps the language lawyers can tell us if the language specifications *require* that b be evaluated. -- Richard Harter, Software Maintenance and Development Systems, Inc. Net address: jjmhome!smds!rh Phone: 508-369-7398 US Mail: SMDS Inc., PO Box 555, Concord MA 01742 This sentence no verb. This sentence short. This signature done.
kers@hplb.hpl.hp.com (Chris Dollin) (04/05/91)
Dave Eisen writes (apropos of the ``xor'' discussion): #define XOR(a,b) (!!(a) ^ !!(b)) does what you want. Hmm ... we can strip one of the !'s from each pair to get (!(a) ^ !(b)) If the XOR is likely to be used in conditional contexts (rather than value contexts) then I'd guess that more compilers could optimise equality tests than ^ instructions (because more machines have some sort of branch-if-(n)eq), so how about #define XOR(a,b) (!(a) != !(b)) -- Regards, Kers. | "You're better off not dreaming of the things to come; Caravan: | Dreams are always ending far too soon."
Sepp@ppcger.ppc.sub.org (Josef Wolf) (04/06/91)
darren@revcan.UUCP (Darren Morbey) writes: ] 1. #define XOR(a,b) ( ( !(a) && (b) ) || ( (a) && !(b) ) ) ] 2. #define XOR(a,b) ( !(a) != !(b) ) ] 3. #define XOR(a,b) ( (a) ? !(b) : (b) ) /* my favourite. */ Waht about #define XOR(a,b) (a) != (b) /* just a suggestion */ Greets Sepp | Josef Wolf, Germersheim, Germany | +49 7274 8047 -24 Hours- (call me :-) | ...!ira.uka.de!smurf!ppcger!sepp | +49 7274 8048 -24 Hours- | sepp@ppcger.ppc.sub.org | +49 7274 8967 18:00-8:00, Sa + Su 24h | "is there anybody out there?" | all lines 300/1200/2400 bps 8n1
brnstnd@kramden.acf.nyu.edu (Dan Bernstein) (04/07/91)
In article <372@smds.UUCP> rh@smds.UUCP (Richard Harter) writes: > #define AND(a,b) ( !(a) ? ((b) && 0) : !!(b) ) > appears to do the trick, modulo typoes. However it occurs to me that a > "clever" optimizing compiler would recognize that ((b) && 0 ) is always > false and bypass the evaluation of b. Perhaps the language lawyers can > tell us if the language specifications *require* that b be evaluated. I'm not much of a language lawyer, but yes, b is evaluated once. ---Dan
volpe@camelback.crd.ge.com (Christopher R Volpe) (04/08/91)
In article <NSfh-D@ppcger.ppc.sub.org>, Sepp@ppcger.ppc.sub.org (Josef Wolf) writes: |>Waht about #define XOR(a,b) (a) != (b) /* just a suggestion */ If a==5 and b==6, do you want XOR(a,b)==1?? |>| Josef Wolf, Germersheim, Germany | +49 7274 8047 -24 Hours- (call me :-) |>| ...!ira.uka.de!smurf!ppcger!sepp | +49 7274 8048 -24 Hours- |>| sepp@ppcger.ppc.sub.org | +49 7274 8967 18:00-8:00, Sa + Su 24h |>| "is there anybody out there?" | all lines 300/1200/2400 bps 8n1 ================== Chris Volpe G.E. Corporate R&D volpecr@crd.ge.com
alan@ukpoit.co.uk (Alan Barclay) (04/11/91)
In article <1991Apr3.184316.11559@dg-rtp.dg.com> barnettr@snaggle.rtp.dg.com (Richard Barnette) writes: > > A B | A XOR B A B | A AND B A B | A AND B > -----+--------- -----+--------- -----+--------- > F F | F F F | F F F | F > F T | T F T | T F T | F > T F | T T F | T T F | F > T T | F T T | T T T | T > > Given A if F, A AND B is always F; given A is T, A OR B is always >T. No such statement can be made for A XOR B; if A is T, A XOR B is I take it that the A AND B table should read F,F,T,T as F AND T is F. -- Alan Barclay iT | E-mail : alan@ukpoit.uucp Barker Lane | BANG-STYLE : .....!ukc!ukpoit!alan CHESTERFIELD S40 1DY | VOICE : +44 246 214241
jhz@cunixa.cc.columbia.edu (Jennifer H. Zemsky) (04/14/91)
In article <1991Apr11.122102.5976@ukpoit.co.uk> alan@ukpoit.co.uk (Alan Barclay) writes: >In article <1991Apr3.184316.11559@dg-rtp.dg.com> barnettr@snaggle.rtp.dg.com (Richard Barnette) writes: >> >> A B | A XOR B A B | A AND B A B | A AND B >> -----+--------- -----+--------- -----+--------- >> F F | F F F | F F F | F >> F T | T F T | T F T | F >> T F | T T F | T T F | F >> T T | F T T | T T T | T >> > >I take it that the A AND B table should read F,F,T,T as F AND T is F. >-- > Alan Barclay either i missed this statement: #define humor 1 or you really didn't recognize the middle table as A OR B, since T AND F is also F. --jhz sorry, no funny sig. maybe later.