absolute value function

Oct 13, 2009 at 8:15pm
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.

Oct 13, 2009 at 8:49pm
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.
Last edited on Oct 13, 2009 at 9:04pm
Oct 13, 2009 at 9:06pm
x^0==x
x^1==!x

7^4==3
111b^100b==011b
3^4==7
011b^100b==111b
Last edited on Oct 13, 2009 at 9:11pm
Oct 13, 2009 at 9:27pm
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.
Last edited on Oct 13, 2009 at 9:37pm
Oct 13, 2009 at 10:12pm
See what happens when you replace the ^ with & or |.
Oct 13, 2009 at 10:47pm
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.
Last edited on Oct 13, 2009 at 10:56pm
Oct 13, 2009 at 11:24pm
Uh... No...
Given that sizeof(x)==4, x|0x7FFFFFFF==abs(x).
Last edited on Oct 14, 2009 at 12:05am
Oct 13, 2009 at 11:42pm
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

Please let me know what I'm doing wrong here.
Last edited on Oct 13, 2009 at 11:45pm
Oct 14, 2009 at 12:05am
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)))

Otherwise, the way you're doing it is fine.
Oct 14, 2009 at 2:25am
The xor mask for both can be had by doing (0 - isNegative(x)). The rest you've got.
Last edited on Oct 14, 2009 at 2:26am
Topic archived. No new replies allowed.