最接近零的Mod

Jon*_*Mee 6 c c++ angle modulo closest

我有一个角度,我需要返回[-180:180]范围内的代表角度.

我写了一个函数来做这个,但它似乎是一个简单的过程,我想知道是否有一个运算符或函数已经这样做:

int func(int angle){
    angle %= 360;

    if(angle > 180){
        angle -=360;
    }else if(angle < -180){
        angle += 360;
    }   
    return angle;
}
Run Code Online (Sandbox Code Playgroud)

我已经为测试预期的功能做了一个实例.

chu*_*ica 3

代码是最优的或者至少接近最优。有些平台可能会通过一些变化而更好地工作。

没有一个 C 整数运算符可以处理这个问题。

对此的挑战是结果的范围是[-180:180]361 个不同的值。目前还不清楚是否允许func(180)退货-180

下一个挑战是让代码在可能溢出的整个[INT_MIN...INT_MAX]范围内工作angle + 180angle %= 360;照顾这个。

以下是 OP 代码的有效变体,它可以在管道机器上运行得更快。它只执行一项%操作 - 可以想象是最昂贵的。正angle回报 [-179:180] 和负angle回报 [-180:179]

int func2(int angle) {
  angle %= 360; 
  return angle + 360*((angle < -180) - (angle > 180));
}
Run Code Online (Sandbox Code Playgroud)

以下是返回值 [-180:179] 的单行代码。它不使用,angle + 180因为可能会溢出。

int func3(int angle) {
  return ((angle % 360) + (360+180))%360 - 180;
}
Run Code Online (Sandbox Code Playgroud)

有一个<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;
}
Run Code Online (Sandbox Code Playgroud)

  • @JonathanMee它在这里起作用是因为第二个参数是360,因为它应该在其他函数中用于mod。 (2认同)
  • @JonathanMee 您的“`remainder` 不起作用”的示例使用 `remainder(-190, 180)`。`func4()` 中的这个答案使用 `remainder(-190, 360)`。 (2认同)