我有一个角度,我需要返回[-180:180]范围内的代表角度。
我已经编写了一个函数来执行此操作,但它似乎是一个非常简单的过程,我想知道是否有一个已经执行此操作的操作符或函数:
int func(int angle){
angle %= 360;
if(angle > 180){
angle -=360;
}else if(angle < -180){
angle += 360;
}
return angle;
}
我已经制作了live example来测试预期的功能。
答案 0 :(得分:3)
我不知道标准的操作符或函数,但你可以用一个表达式来完成:
((angle + 180) % 360) - 180;
注意:我的原始答案使用了以下表达式:
Customer Codes
111 A
111 B
111 C
222 A
222 B
333 A
这是更整洁,但依赖负数的模数为正。有些语言(如Python)具有这些语义,但C和C ++通常不具备这些语义。上面的表达式通过添加360的额外移位来解释这一点。
答案 1 :(得分:3)
代码是最佳的或至少几乎是如此。某些平台可能会因某些变化而更好地工作。
没有一个C整数运算符可以处理这个。
对此的挑战是问题是结果范围是[-180:180]
,这是361个不同的值。目前还不清楚是否允许func(180)
返回-180
。
下一个挑战是让代码在整个[INT_MIN...INT_MAX]
范围内工作,因为angle + 180
可能会溢出。 angle %= 360;
负责照顾。
以下是OP代码的有效变体,可以在管道式机器上运行得更快。它只进行一次%
操作 - 可以想象是最昂贵的操作。正面angle
返回[-179:180],负面angle
返回[-180:179]
int func2(int angle) {
angle %= 360;
return angle + 360*((angle < -180) - (angle > 180));
}
以下是一行返回值[-180:179]。它不会使用angle + 180
,因为它可能会溢出。
int func3(int angle) {
return ((angle % 360) + (360+180))%360 - 180;
}
<math.h>
函数double remainder(double x, double y);
符合OP的目标。 (也许从C99开始可用。)它将返回FP值[-180:180]。注意:int
的整数范围可能超过double
可以准确表示的范围。
int func4(int angle) {
angle = remainder(angle, 360.0);
return angle;
}
答案 2 :(得分:1)
您需要的是简单的wrap
函数实现:
#include <stdio.h>
int wrap(int value, int lower_bound, int upper_bound) {
int range = upper_bound - lower_bound;
value -= lower_bound; // shift from [lower, upper) to [0, upper - lower)...
value %= range; // ... so modulo operator could do all the job
if (value < 0) { // deal with negative values
value += range;
}
value += lower_bound; // shift back to [lower, upper)
return value;
}
void show(int value, int lower_bound, int upper_bound) {
printf("%4d wrapped to the range of [%d, %d) is %d\n",
value, lower_bound, upper_bound,
wrap(value, lower_bound, upper_bound)
);
}
int main(void) {
// examples
show(0, -180, 180);
show(-200, -180, 180);
show(720, -180, 180);
show(1234, -180, 180);
show(5, 0, 10);
show(-1, 0, 10);
show(112, 0, 10);
show(-3, -10, 0);
show(7, -10, 0);
show(-11, -10, 0);
return 0;
}