如何设置/改变变量的绝对值?
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、.. .),并且需要将参数转换为无符号类型(或依赖于未定义的行为)。
大家都知道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、.. .),并且需要将参数转换为无符号类型(或依赖于未定义的行为)。