我正在制作一个函数,它接受3个无符号的长整型,并应用余弦定律来确定三角形是钝角,锐角还是直角三角形。我应该在使用变量之前将其转换为双精度吗?
void triar( unsigned long long& r,
unsigned long long x,
unsigned long long y,
unsigned long long z )
{
if(x==0 || y==0 || z==0) die("invalid triangle sides");
double t=(x*x + y*y -z*z)/(2*x*y);
t=acos (t) * (180.0 / 3.14159265);
if(t > 90) {
cout<<"Obtuse Triangle"<<endl;
r=t;
} else if(t < 90){
cout<<"Acute Triangle"<<endl;
r=t;
} else if(t == 90){
cout<<"Right Traingle"<<endl;
r=t;
}
}
最佳答案
如果没有浮点运算,通常就没有理由不进行转换。但是,还存在从unsigned long
到double
的隐式转换,因此您通常也可以完全不进行强制转换。
在包括您在内的许多情况下,您只能将一个参数强制转换为仅对特定操作强制double
算术。例如,
double t = (double)(x*x + y*y - z*z) / (2*x*y)
这样,除法运算以外的所有运算都是以整数算术运算的,因此速度更快。为了避免在分割过程中被截断,仍然需要强制转换。
您的代码包含浮点参数的比较。但是,浮点运算几乎不可避免地会降低精度。避免精度受限,或分析和控制精度。
如果您有足够宽的整数类型可以使用,请选择一个出色的姊妹答案中所述的仅整数解决方案
始终避免从弧度转换为度,除非是向人类展示
从数学库头文件中获取π的值(不幸的是,这取决于平台-尝试
_USE_MATH_DEFINES
+ M_PI
或尝试使用boost::math::constants::pi<double>()
(如果已使用Boost库的话)),或进行解析表示。例如,std::atan(1)*2
是直角。如果选择双精度,并且最终差值小于例如
std::numeric_limits<double>::min() * 8
,则可能无法说明三角形,并且返回的分类基本上是虚假的。 (我将值设为8,您可能会损失比三多的位数。)