2015-02-24 62 views
4

我试图找到该tan功能正确的域名,我知道如何检查是否Math.cos(角)= 0

tan x = sinx/cos x 

tan是不确定时cos x = 0。所以

我想检查是否cos x为0

if (Math.Cos(x).Equals(0)) 
{ 
    // do stuff 
} 

但由于Math.Cos返回但这是不正确6.123....E-17 如何O检查的COS == 0?

+0

因为这种采用双精度,你应该加上一个合理的误差范围。 – 2015-02-24 15:49:24

+0

奇怪的是,之前没有人试图比较双打...... http://www.bing.com/search?q=C%23+double+compare似乎正在产生一些结果 - 可能这不是第一次.. – 2015-02-24 15:56:15

+1

只有当参数正好是+/- pi/2时,它才会恰好为0。从来没有,浮点数没有足够的准确性。 – 2015-02-24 15:59:47

回答

11

您需要扩大您的期望一点 - 为了Math.Cos(x)是真正等于0,你要么需要在Cos不准确(这会发生,当然)或x有一个非理性的价值。

相反,你应该制定出一些宽容 - 为Math.Cos一些数值范围,其是非常接近为0。例如:

if (Math.Abs(Math.Cos(x)) < 1e-15) 

1e-15拾取非常随意 - 你应该制定出你想让它成为你特定的任务。 (这当然会给出相当大的值tan ...)

+0

如何使用'double.Epsilon'? – user1620220 2015-02-24 15:52:14

+2

'double.Epsilon'太小了。 – 2015-02-24 15:53:12

+0

http://stackoverflow.com/questions/328475/should-we-compare-floating-point-numbers-for-equality-against-a-relative-error – 2015-02-24 15:53:16

2

问题是,您需要比较它不是直接的,但由于事实如何在内存中表示浮点值,因此具有一定的准确性。

您可以通过使用像这样的一些代码修正:

const double Epsilon = 0.0001; 

if (Math.Cos(x) < Epsilon) 
{ 
    // Code here 
} 

而且,因为它使代码难以阅读有没有点写Math.Cos(X).Equals(东西)。

如果你想为什么你的代码不工作,你可以看看它在这里更多的信息:http://www.parashift.com/c++-faq/floating-point-arith.html

这是针对C++常见问题解答,但同样的事情适用于你的情况。

4

如果您的问题正在从Math.Tan收到例外,Math.Tan不会丢失。它可以做的唯一的事情就是返回Double.NaN和(也许)Double.PositiveInfinity/Double.NegativeInfinity,所以只需查询到:

double t = Math.Tan(something); 

if (!double.IsInfinity(t) && !double.IsNaN(t)) 
{ 
    // Do Something 
}