我正在制作一个函数,它接受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 longdouble的隐式转换,因此您通常也可以完全不进行强制转换。

在包括您在内的许多情况下,您只能将一个参数强制转换为仅对特定操作强制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,您可能会损失比三多的位数。)

09-07 02:21
查看更多