Friday, May 13, 2022

Dangerous while loop

Today a program I am writing stopped responding. After some debugging effort, I came across a 3rd party function that limited an input angle to the [-180, 180] degrees interval. It was using a while loop to increment or decrement the angle. Unfortunately, I was passing an uninitialized variable to it and its value was -9.2...e+61. Such a large value would take years for the function to limit. Below is the original function constrainAngleWhile(), together with much better alternatives:

//Demonstrate different methods to limit an angle to the [-180, 180] degree interval.
//To quickly test, paste code to https://www.onlinegdb.com/online_c++_compiler
//Şamil Korkmaz, May 2022
#include <iostream>
#include <math.h>
using namespace std;
//https://stackoverflow.com/a/11498248/51358
double constrainAngleMod(double x) {
x = fmod(x + 180,360);
if (x < 0) x += 360;
return x - 180;
}
double constrainAngleWhile(double x) {
double limitedX = x;
//Note that the while loops below will take a long time if the input x is a large value.
//For example, an unitialized variable can have a value like -9.2...e+61 which would take years!
while (limitedX < -180) limitedX += 360;
while (limitedX > 180) limitedX -= 360;
return limitedX;
}
int main() {
cout << "Calculating...\n";
//Using remainder(): https://stackoverflow.com/a/11503585/51358
cout << remainder(180, 360) << ", " << constrainAngleWhile(180) << endl;
cout << remainder(181, 360) << ", " << constrainAngleWhile(181) << endl;
cout << remainder(-181, 360) << ", "<< constrainAngleWhile(-181) << endl;
cout << remainder(-359, 360) << ", "<< constrainAngleWhile(-359) << endl;
cout << remainder(359, 360) << ", "<< constrainAngleWhile(359) << endl;
cout << remainder(-360, 360) << ", "<< constrainAngleWhile(-360) << endl;
cout << remainder(360, 360) << ", "<< constrainAngleWhile(360) << endl;
double angle_deg = 1e12;
cout << remainder(angle_deg, 360) << ", " << constrainAngleMod(angle_deg) << endl;
cout << constrainAngleWhile(angle_deg) << endl;
cout << "Finished.\n";
return 0;
}
view raw limitAngle.cpp hosted with ❤ by GitHub

No comments:

Post a Comment