One part of our assignment this week is really giving me problems. What we have to do is create several functions (isNegative(),isEven(), isOdd(), negate(), absoluteValue(), and subtract()). The trick is that we are only allowed to use and, or, not, and xor. No if's, loops, or branching. We are learning how to use two's complement number systems. I have all of them done up to the absolute value one and I'm stuck. I know that if I pass the function a negative number, all I have to do is take the xor value of that number and add 1 to get it's absolute value, and for a positive number just return that number. The problem is that we cant use an if-then.
He gave us a hint, which has me more confused than ever. Here it is:
Hint: the key here is to create a mask from the data such that when you derive the mask from a positive data value and then exclusive or the mask with the data, the result will be the data, but when you derive the mask from a negative data value and then exclusive or the mask with the data, the result will be the complement of the data. Likewise, derive a value from the data such that when it is derived from a positive value and added to the data, the result is just the data, but when it is derived from a negative value and applied to the data the result is data+1.
I know that even though we are using C++ for this class, this problem is maybe more of a computer science problem than strictly a C++ problem, but I've always gotten valuable help from people here, so I thought I would ask.
I don't want someone to give me an answer, but maybe you could point me in a right direction, or make the hint a little more understandable.
ok, here's what I take from the hint:
the first part:
positive data xor mask -> data
negative data xor mask -> complement of data
so I know if I take the data and xor it with 0, I get the data. And if I take the data, and !(xor) it with 0, I get the complement. But again, I can't use an if statement to differentiate xor from !(xor)
How the heck can I make the same mask do different things based on whether the leftmost bit is a 1 or a 0???
The second part of the hint is easy:
positivedata + value = data
negativedata+value=data+1
I can use the isNegative() function I created earlier in the assignment to do this
newdata = data + isnegative(); isNegative is bool, so it returns 1 if the number is negative, 0 if it is positive.
That's exactly what I was thinking, that I could use isNegative(), so I could xor the initial value with a 1 if it is negative, or 0 if it is positive, which would work perfectly. the problem I can't figure out is that if x is negative, I would be xor'ing it with 1, when I need to xor it with 11111111(4 byte ints). I can't figure out how to make that change using only shifts, ands, ors, xors, and nots. If I could change a 00000001 to 11111111, while allowing a 0 to stay 00000000, I would be good.
Ha!!!! if I take the value, and or it with isNegative(), a positive value will be or'd with 0, which will give me back the data, and a negative value will be or'd with 1, which will give me the complement!!
Thanks so much Helios.
(positivevalue || isNegative())+isNegative() = value;
(negativevalue || isNegative()) + isNegative() = -value;
No, after working it through, I still have the same problem, isNegative() still returns 1, and I need the value to be 11111111.
now I'm totally confused. We were taught that to reverse the sign of a two's complement number we were supposed to take the complement and add 1.
like
1111 , which is -1 in twos complement
0000 , complement of above
0001 ,and add 1, to get the opposite, or +1
so to get the absolute value of a negative number, complement all the digits and add 1
to get the absolute value of a positive number, dont complement and dont add
so, to complement the negative, xor by 1111 and add isNegative(), which is 1
the positive we need to xor by 0000, and add isNegative(), which is 0
so if the number is negative (isNegative() is 1), we need to or by 1111
and if the number is positive (isNegative() is 0), we need to or by 0000
the positive number is easy, because 0 is the same as 0000
the negative is not, because 1 is not the same as 1111
Sorry, I always do this. Well, from time to time. You're right, the above formula doesn't work.
This one does, but it's probably a bit too complex: (a^(a>>(sizeof(a)*8-1))+((unsigned)a>>(sizeof(a)*8-1)))