如何设置/改变变量的绝对值?

How to set / change the absolute value of variable?

大家都知道abs()函数得到变量的绝对值。是否有类似的功能或有效的方法来设置它忽略标志?

实际例子: 电机速度控制的强制最小值

if (abs(speed) < 50 && speed != 0)
{
    if (speed < 0)
        speed = -50;
    else
        speed = 50;
}

我正在寻找标准化函数或巧妙的位操作单行代码。 将上面的 if 包装到函数或宏中是显而易见的。

结合你可以找到的答案,例如Fast sign of integer in C:

speed=((speed > 0) - (speed < 0)) * theNewValue;

你基本上只是想保留符号,然后乘以一个新的范数。

这取决于您的平台。由于您没有说您的目标系统是什么,我将假设您的整数使用符号+幅度表示。 ;-)

int setabs(int sign, int magnitude)
{
    static const unsigned mask =- 0^0;
    assert(mask); // in case it's used on weird (two's complement) systems
    return (int)((unsigned)sign&mask | (unsigned)magnitude&~mask);
}

然后你可以写

speed = setabs(speed, 50);

基本上就是signum函数

speed = 50*sgn(speed);

有一个 standard function 这个

speed = copysign(50, speed);

然而,这对于整数类型来说效率不高。

sgn() 函数可以使用您可以找到的各种其他方式实现 here

speed = ((speed > 0) - (speed < 0))*50;

您正在寻找与标准 copysign() 函数等效的整数。

最简单的方法就是将 magnitude 参数的绝对值乘以 sign 参数的符号,使用标准方法之一获得:

int setabs(int magnitude, int sign)
{
     return magnitude
        * ((magnitude > 0) - (magnitude < 0))
        * ((sign > 0) - (sign < 0));
}

测试证明:

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);
}

如果乘法对您来说很昂贵,那么我们可以使用两个布尔值的减法来制作稍微便宜一点的版本(通过相同的测试集):

int setabs(int magnitude, int sign)
{
    return magnitude
        * ((magnitude > 0 == sign >= 0) - (magnitude > 0 == sign <= 0));
}

任何 bit-manipulation 技术将取决于您的平台对负整数使用哪种表示形式(sign-magnitude、一个's-complement、两个's-complement、.. .),并且需要将参数转换为无符号类型(或依赖于未定义的行为)。