What does ^= mean in Objective-C? - objective-c

I found this part of the code "^ =" in some old project, I saw how it changes state when I call "status ^ = YES;". Can someone explain to me what this is?
BOOL status = YES;
status ^= YES;

https://en.wikipedia.org/wiki/Bitwise_operations_in_C
The bitwise XOR (exclusive or) performs a logical XOR function, which is equivalent to adding two bits and discarding the carry. The result is zero only when we have two zeroes or two ones. XOR can be used to toggle the bits between 1 and 0. Thus i = i ^ 1 when used in a loop toggles its values between 1 and 0.
So status ^= YES is a wiseass way of toggling between 1 and 0, aka YES and NO. Mere mortals would say status = !status.

Related

Is it possible to simplify the setter of this bitmask wrapper? [duplicate]

It's common to perform a check and set/clear a flag, eg:
if (some_test) {
flag |= SOME_FLAG;
}
else {
flag &= ~SOME_FLAG;
}
A convenient way around this I found so far is...
flag = (some_test) ? (flag | SOME_FLAG) : (flag & ~SOME_FLAG);
This could be made into a macro and its OK, but is there some bit-twiddeling magic to avoid referencing flag twice?
(in case multiple instantiations of flag causes overhead).
Example of what I'm looking for (if C could do ternary operations on operators), is...
flag ((some_test) ? (|=) : (&= ~) SOME_FLAG;
The example above is only to describe what I'm looking for, of course it wont work in its current form.
flag |= SOME_FLAG
is an expression, so you can use a macro
#define SET_FLAG(flag, some_test) \
((some_test) ? ((flag) |= SOME_FLAG) : ((flag) &= ~SOME_FLAG))
which evaluates flag only once, and when you use it, you need to type flag only once.
SET_FLAG(a->b->c->d, test);
I know you don't want to access flag twice. But you should be sure that is where the cost is. Often, the conditional jump is more expensive. On the last embedded processor I worked on, the fastest code would have looked like this:
flag &= ~(SOME_FLAG);
flag |= (some_test!=0) * SOME_FLAG;
If you want to define a macro and have it avoid evaluating the mask twice then you could do it like this:
#define SETT(FLAG, MASK_T, MASK, TEST) \
do {\
MASK_T mask = (MASK);\
FLAG &= ~mask;\
FLAG |= ((TEST) != 0) * mask;\
}\
while(false)
#define SET(FLAG, MASK, TEST) SETT(FLAG, unsigned, MASK, TEST)

How to set bits on the TI TM4C123G launchpad

I have a question about how bits are set(or cleared) on the TI launchpad registers. It seems sometimes they are bitwise or'd and other times they are set by just an assignement statement. For example, there is the register that is the clock gate and bit 5 must be set in order to be able to use GPIO Port F:
#define SYSCTL_RCGC2_R (*((volatile unsigned long *)0x400FE108))
SYSCTL_RCGC2_R = 0x00000020; //What are the values of all the bits now?
Also, I've seen bits set by bitwise or:
SYSCTL_RCGC2_R |= 0x00000020;
SYSCTL_RCGC2_R = 0x00000020 ;
Sets all bits regardless of their current state. In this case all but b5 are zeroed.
SYSCTL_RCGC2_R |= 0x00000020 ;
Sets only b5, leaving all other bits unchanged. The |= assignment is equivalent to:
SYSCTL_RCGC2_R = SYSCTL_RCGC2_R | 0x00000020 ;
i.e. whatever SYSCTL_RCGC2_R contains is OR'ed with 0x00000020. So b5 must become 1 while all other bits remain unchanged because x OR 0 = x while x OR 1 = 1.
Similarly you can clear an individual bit by AND'ing an inverted bit-mask thus:
SYSCTL_RCGC2_R &= ~0x00000020 ;
because ~ reverses the bits (0xffffffdf), and x AND 0 = 0 while x AND 1 = x.
Note that none of this is specific to TI Launchpad or GPIO registers, it is universal to the programming language for any platform or integer data object.
This is basic C language operator behavior and nothing special about TI Launchpad. The assignment operator sets or clears every bit of the register. The bitwise OR operator sets the bits specified but doesn't clear any bits that were already set. Use a bitwise OR when you want to set a portion of the register without changing the rest. (A bitwise AND operator can be used to clear a portion without changing the rest.)

Understanding weird logical operators in smalltalk

So my problem is the following:
When char = 0
boolean = char ~= 0 & char ~= 256
evaluates to true and if I invert the statements like so:
boolean = char ~= 256 & char ~= 0
I get false.
What's happening?. I am expecting false on both cases.
As #Uko said, you must understand the precedence of messages: all binary messages (+ = < & ~= etc..) are evaluated from left to right.
Thus you evaluate:
(((boolean = char) ~= 256) & char) ~= 0
I think you were after:
boolean := (char ~= 256) & (char ~= 0).
So what happens with your expression ?
booleanis presumably unitialized (thus nil)
char is 0.
boolean = char is false.
false ~= 256 is true.
true & char is char (see below why)
char ~= 0 is false (since char = 0)
If you invert 0 and 256, only the last step changes and awnswer true.
The interesting part is the implementation of message & in class True: it probably does not assert that the parameter is a Boolean and looks like:
& aBoolean
^aBoolean
If you pass something that is not a Boolean, (like 0 in your case), it will return this thing, whatever surprising it can be...
If you use an IDE (Squeak/Pharo/Visualworks/Dolphin... but not gnu Smalltalk) I suggest you use the menu Debug It and evaluate the expression step by step in the Debugger.
Last, note that char is probably not a good name in Smalltalk context: it might be misleading. Indeed, if it holds 0, it's rather an Integer, not a Character.
There is something we are repeating in some answers that I think deserves further clarification. We say evaluation proceeds from left to right. True, but the actual semantics of messages is:
First evaluate the receiver, then the arguments in order; finally send the message.
Since the Smalltalk VM is stack based, this rule means that:
The receiver is evaluated first and the result is pushed on the stack.
The arguments are evaluated in order and their results pushed on the stack.
The message is sent
Item 3 means that the method that the send invokes will find the receiver and the arguments in the stack, in the order defined above.
For instance, in
a := 1.
b := 2.
b := a - (a := b)
variable b will evaluate to (1 - (a := 2)) = -1 and a to 2. Why? Because by the time the assignment a := b is evaluated the receiver a of the subtraction has already been pushed with the value it had at that time, i.e., 1.
Note also that this semantics must be preserved even if the VM happens to use registers instead of the stack. The reason is that evaluations must preserve the semantics, and therefore the order. This fact has an impact on the optimizations that the native code may implement.
It is interesting to observe that this semantics along with the precedence unary > binary > keyword support polymorphism in a simple way. A language that gives more precedence to, say, * than + assumes that * is a multiplication and + an addition. In Smalltalk, however, it is up to the programmer to decide the meaning of these (and any other) selectors without the syntax getting in the way of the actual semantics.
My point here is that "left to right" comes from the fact that we write Smalltalk in English, which is read from "left to right". If we implemented Smalltalk using a language that people read from "right to left" this rule would be contradicted. The actual definition, the one that will remain unchanged, is the one expressed in items 1, 2 and 3 above, which comes from the stack metaphor.

Why does the unary bit inversion operator not invert the value of a BOOL?

I want to invert the value of a BOOL every time I detect a tap. The default value of the BOOL is NO and the first time I tap it inverts it to YES. On subsequent taps the value stays as YES.
#property(nonatomic, assign) BOOL isDayOrNight; //property in timeDayChart object.
self.timeDayChart.isDayOrNight = ~self.timeDayChart.isDayOrNight; //This is done in a VC.
I had to change it to this:
self.timeDayChart.isDayOrNight = !self.timeDayChart.isDayOrNight;
to achieve my desired results. I would like to know why ~ did not work as expected.
BOOL is defined as a signed char in objc.h:
typedef signed char BOOL;
and YES and NO are defined like so:
#define YES (BOOL)1
#define NO (BOOL)0
So ~YES is -2, which is not the same as NO.
In (Objective-)C(++) when a Boolean value is required, such as in an if or as an operand to &&, actually take an integer value and interpret 0 as false and non-zero as true. The logical, relational and equality operators all also return integers, using 0 for false and 1 for true.
Objective-C's BOOL is a synonym for signed char, which is an integer type, while NO and YES are defined as 0 and 1 respectively.
As you correctly state ~ is the bit inversion operator. If you invert any integer containing both 0's and 1's the result will also do so. Any value containing a 1 bit is treated as true, and inverting any such value other than all 1's produces a value with at least one 1 bit which is also interpreted as true.
If you start with all 0's then repeated inversion should go all 1's, all 0's, all 1's - which is true, false, true etc. (but not YES, NO, YES, etc.). So if you are starting with 0 then either you are not always using inversion or you are testing explicitly for YES rather than true.
However what you should be using, as you figured out, is ! - logical negation - which maps 0 to 1 and non-0 to 0 and so handles "true" values other than 1 correctly.
HTH
Find a book about the C language. Check what it says about the ~ operator and the ! operator. ~ inverts all bits in an integer, and BOOL is defined as an integer type. So NO = all bits zero will be changed to all bits set, which is not the same as YES, and YES = all bits zero except the last bit = 1 will be changed to all bits set except the last bit = 0.
You are better off using this idiom to toggle a BOOL value:
self.timeDayChart.isDay = self.timeDayChart.isDay ? NO : YES;
(I deliberately changed the naming of your property)

Why do a lot of languages lack a logical XOR operator?

Off the top of my head, I cannot think of a single language I've used that had a logical exclusive or operator, but all have logical and bitwise and and or operators.
Looking around, the only reason to this that I could find was that exclusive or cannot be short circuited, so a logical version would be useless, which I really can't see being the case. The reason it came to my attention that most languages lack this is that I needed it (I was using Ruby, so I wrote a method to convert an integer to a boolean, and then use bitwise XOR, which on booleans acts like logical XOR).
Just using bitwise XOR does not work either, because it will give a different result.
0b0001 ^ 0b1000 = 0b1001 (True)
0b0001 XOR 0b1000 = False
// Where ^ is bitwise exclusive or and XOR is logical exclusive or
// Using != (not equal to) also doesn't work
0b0001 != 0b1000 = True
So why is it that most languages do not include a logical exclusive or operator?
Edit: I added an example with how != also does not do what I want, it almost does, but falls into the same problem that using bitwise exclusive or does, it only works if you know that you are working with zero or one, and not any other number.
And to note, this is assuming that language uses zero as false and nonzero as true.
Nearly every language has a logical XOR. The symbol they use for it varies, but regardless of the symbol, most people pronounce it "not equal".
Edit: for those who doubt, test code for three variables:
#include <iostream>
int main() {
for (int i=0; i<2; i++)
for (int j=0; j<2; j++)
for (int k=0; k<2; k++) {
std::cout << "\n!=" << (i!=j!=k);
std::cout << "\t^ " << (i^j^k);
}
return 0;
}
What do you mean by "logical XOR operator"? I'm not sure what result do you expect from your examples, but here's my answer:
a (logical XOR) b is the same as bool(a) != bool(b)
Inequality is a logical XOR. Since you already have the bitwise XOR version, you don't need a special operator for the logical one.
You can also write !a ^ !b to get the same effect as a logical xor.
You probably don't find logical xor in programming languages because:
it doesn't generate very efficient assembly code
is not needed very often
language designers have to put the line somewhere, why not NAND, NOR, NXOR, etc.
OK, so you're looking for a bytewise exclusive-or versus a bitwise exclusive-or. It seems like you're looking for something that will operate on a byte as "on" or "off", as thought the bytes are "0" or "nonzero", then XOR them. It really sounds like you're looking to compress each byte into a single bit indicating true or false. So, it sounds like you want (a!=0)^(b!=0)
a b a YOURXOR b a!=0 b!=0 (a!=0)^(b!=0)
0 0 0 0 0 0
0 1 1 0 1 1
1 0 1 1 0 1
7 0 1 1 0 1
0 7 1 0 1 1
3 7 0 1 1 0
7 3 0 1 1 0
7 7 0 1 1 0
As for why that's not in every language... that I can't really answer. However it's not all that difficult to implement with the building blocks of bitwise xor available in every language, and no language offers all possible functionality - they just offer enough to let you build the extended functionality you might need. Oh, and if this were a popular enough problem, you'd expect to see libraries or macros all over the place for it; while I may not have made a sufficient search for such libs/code, I didn't find any myself, indicating that the requirement is either trivial to write, or a niche requirement.
The only reason I can think of is that the operation is relatively rare. I don't see why something like ^^ couldn't be assigned to it though, maybe people who design languages want to avoid operator clutter.
As to it being useless because it can't be short-circuited, in many strongly typed languages you can't use the bitwise XOR operator to compare booleans without casting back and forth, in which case even a non-short circuiting logical XOR would make sense to have.
Probably because XOR isn't commonly needed as a logical operator, and you can do it almost as easily as this:
// foo xor bar
(foo & !bar) || (bar & !foo)
// or like this (assuming foo and bar are booleans)
!(foo==bar)
// assume boleans that can be cast as integers with true=1 and false=0
// foo XOR bar XOR baz XOR alice
((int)foo + (int)bar + (int)baz + (int)alice)&0b1