C++ C++;:除以cos(x)安全吗?

C++ C++;:除以cos(x)安全吗?,c++,C++,我必须调试一些旧代码。一个问题是识别并消除所有浮点除法。 它们并不多,但我发现最常见的是: dA = bB / cos(x); 还有罪恶和晒黑x通常是以度为单位的坐标,因此tan、cos和sin很容易为零。这段代码已经存在并运行了几十年,因为它是安全关键的,所以已经在各地进行了测试 edit1:x是一个double,通常在从UTM转换后生成。以度为单位的值在-180.0到+180.0之间 编辑2:当然是弧度,它会被转换。但它可能仍然是零 所以我的问题是,为什么它从未崩溃过?我错过什么了吗 编辑

我必须调试一些旧代码。一个问题是识别并消除所有浮点除法。 它们并不多,但我发现最常见的是:

dA = bB / cos(x);
还有罪恶和晒黑
x
通常是以度为单位的坐标,因此
tan
cos
sin
很容易为零。这段代码已经存在并运行了几十年,因为它是安全关键的,所以已经在各地进行了测试

edit1:
x
是一个
double
,通常在从UTM转换后生成。以度为单位的值在-180.0到+180.0之间

编辑2:当然是弧度,它会被转换。但它可能仍然是零

所以我的问题是,为什么它从未崩溃过?我错过什么了吗

编辑3我跟踪了所有评论,找到了适合我的答案。这是由一个严重的异常开始的。我们得到一个异常的原因是我们内置了其他人的代码(由客户提供),这是非常数学的。他们已经打开了浮点异常(/fp:except),如果需要的话,这当然可以。然而,他们并没有再次关闭它,所以我们的代码开始抛出以前从未出现过的异常。这是通过dll而不是exe调用新东西来弥补的,但留给我的是让人们再次快乐的行动。 我正在看每一个除法的代码,看看它是否可以被零除法,如果这是一件坏事,既然我现在知道三角运算对NaN很满意,这也不会太糟糕。我还得检查一下。哎哟。

double
有。除以
0
得到这个特殊值

请注意,
x
的单位应为弧度,而不是度

刚刚在一些C++编译器中测试:

#include <iostream>
#define USE_MATH_DEFINES
#include <cmath>

int main()
{
  std::cout << (1 / std::cos(M_PI_2)) << "\n";
  std::cout << (1 / std::sin(0)) << "\n";
}
所以
1/cos(M_PI_2)
可以是非常大的数字,甚至不是无穷大。我想它可以用于日常的数值计算。

double
has。除以
0
得到这个特殊值

请注意,
x
的单位应为弧度,而不是度

刚刚在一些C++编译器中测试:

#include <iostream>
#define USE_MATH_DEFINES
#include <cmath>

int main()
{
  std::cout << (1 / std::cos(M_PI_2)) << "\n";
  std::cout << (1 / std::sin(0)) << "\n";
}

所以
1/cos(M_PI_2)
可以是非常大的数字,甚至不是无穷大。我想它可以用于日常的数值计算。

旁注:函数余弦在90度(或π/2弧度)时为零。从空间的角度来看,这与。。。垂直的。假设您的代码从未处理过垂直的东西,那么它很可能会继续运行一段时间而不会崩溃。请分享更多关于x的详细信息,x应该是弧度,而不是度。

旁注:函数余弦在90度(或π/2弧度)时为零。从空间的角度来看,这与。。。垂直的。假设您的代码从未处理过垂直的东西,那么它很可能会继续运行一段时间而不会崩溃。请分享更多关于
x
的详细信息,x应该是弧度,而不是度。

代码运行是因为
cos(x)
的零位于
pi/2+k*pi;k欧元Z
。但是,
pi
不能精确表示。因此,不可能出现完全零。

代码运行,因为
cos(x)
的零位于
pi/2+k*pi;k欧元Z
。但是,
pi
不能精确表示。因此,不太可能完全为零。

广义而言,因为只有具有零余弦的实值是无理的(即,
pi/2的奇数倍),并且浮点值不能表示无理实值,所以不可能存在具有零余弦的浮点值

在非关键代码中,这种参数可能就足够了。在高关键性(如安全关键性)规范中,这是不可接受的(取决于系统要求)

类似地,像“它已经在各地测试过”这样的声明也不一定可以接受——如果您想使用这样的论点(在某些安全标准中更正式地称为服务历史论点),那么您就有责任证明它的合理性

我希望,如果系统之前被认为可用于安全相关应用中,如您所说,那么会有一些情况分析,在这种情况下,类似于
dA=bB/cos(x)
的语句可能会产生错误的结果(例如浮点溢出、被零除等)。该分析将取决于如何实现
cos()
函数,例如,它在您选择的标准库中使用的算法。然后,考虑到程序输入的可能范围,分析将考虑任何错误结果对整个系统行为(不仅仅是程序)的影响,以及发生的可能性。本质上,这意味着一个完整的风险评估——如果风险低到可以接受的程度(在系统环境中),那么它将被接受


这样说吧:假设这个代码是控制电梯的固件的一部分。您将更新此代码,重新编译它,并将更新的固件安装到多个电梯中。现在想象一下,如果
dA
的值影响电梯的运行速度,那么危险在于电梯以足以杀死乘客的速度撞击地面。许多你关心的家庭成员经常使用你正在更新的电梯。你会接受“到处都在测试”的说法吗?或者您想要一个更稳健的参数吗?

广义而言,因为只有零余弦的实值是无理的(即,
pi/2的奇数倍),浮点值不能表示无理实值,即