C++度与弧度互相转换——记一个隐晦的BUG

度与弧度互相转换在软件工程里是非常常见的操作。在C++代码中,可以通过定义宏来方便快捷地进行度与弧度的互相转换。然而,这看似平常的操作,如果疏忽,可能会引入一些比较隐晦的BUG,只有在特定情况下才会被触发。这里的示例来自与本人调试算法时最终定位出来的问题,现将其剥离出来进行说明,引以为戒。

版本一

#include <iostream>
using namespace std;

#define PI 3.1415926535897932384626433832795
#define DEG2RAD(x) (x/180*PI)
#define RAD2DEG(x) (x/PI*180)
int main()
{
	double rad = DEG2RAD(90);
	cout << "rad = " << rad << endl;
	double deg = RAD2DEG(3.14);
	cout << "deg = " << deg << endl;
	return 0;
}

显然,3.14从弧度转换为度接近180度,这个是正确的。然而90度转换为弧度是0?明显不对,这是因为90和180都是整数,通过整除以后就是0,正确写法应该把180改为180.0,这样除以浮点数以后结果还是浮点数。

版本二

#include <iostream>
using namespace std;

#define PI 3.1415926535897932384626433832795
#define DEG2RAD(x) (x/180.0*PI)
#define RAD2DEG(x) (x/PI*180.0)
int main()
{
	double rad = DEG2RAD(90);
	cout << "rad = " << rad << endl;
	rad = DEG2RAD(90 + 30);
	cout << "rad = " << rad << endl;
	double deg = RAD2DEG(3.14);
	cout << "deg = " << deg << endl;
	deg = RAD2DEG(3.14 + 3.14);
	cout << "deg = " << deg << endl;
	return 0;
}

 

这里第一个rad和deg计算结果都是对的,但是第二个rad和deg明显是错的。120度对应的弧度不可能这么大,另外两个3.14相加对应的度应该接近360度才对。结合宏定义的本质,仔细分析就会发现问题所在:

DEG2RAD(90 + 30)等价于(90 + 30/180.0*PI)

RAD2DEG(3.14 + 3.14)等价于(3.14 + 3.14/PI*180.0)

x没有加括号!!!

正确版本

#include <iostream>
using namespace std;

#define PI 3.1415926535897932384626433832795
#define DEG2RAD(x) ((x)/180.0*PI)
#define RAD2DEG(x) ((x)/PI*180.0)
int main()
{
	double rad = DEG2RAD(179);
	cout << "rad = " << rad << endl;
	rad = DEG2RAD(20.5 + 25.6);
	cout << "rad = " << rad << endl;
	double deg = RAD2DEG(3.14);
	cout << "deg = " << deg << endl;
	deg = RAD2DEG(3.14 + 0.146);
	cout << "deg = " << deg << endl;
	return 0;
}

 

总结:当分子分母都是整数但结果要求为浮点数时,注意整除的影响;用宏定义进行表达式计算时,注意隐含的优先级操作。

 

  • 7
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值