You're looking for an integer equivalent of the standard copysign()
function.
The simplest way to do that is simply to multiply the absolute value of the magnitude
argument by the sign of the sign
argument, using one of the standard methods to obtain that:
int setabs(int magnitude, int sign)
{
return magnitude
* ((magnitude > 0) - (magnitude < 0))
* ((sign > 0) - (sign < 0));
}
Tests to demonstrate:
int main()
{
return
+ (setabs(50, 1) != 50)
+ (setabs(50, 0) != 0)
+ (setabs(50, -1) != -50)
+ (setabs(-50, 1) != 50)
+ (setabs(-50, 0) != 0)
+ (setabs(-50, -1) != -50);
}
If multiplications are expensive for you, then we can use subtraction of two booleans to make a slightly cheaper version (passing the same set of tests):
int setabs(int magnitude, int sign)
{
return magnitude
* ((magnitude > 0 == sign >= 0) - (magnitude > 0 == sign <= 0));
}
Any bit-manipulation techniques will depend on which representation is used by your platform for negative integers (sign-magnitude, one's-complement, two's-complement, ...), and will require casting the arguments to unsigned types (or rely on undefined behaviour).