【问题标题】:Incorrect results from C++ math library's trigonometry functionsC++ 数学库的三角函数的结果不正确
【发布时间】:2011-11-21 10:18:44
【问题描述】:

我目前正在从事一个我已经做了近一年的个人项目。我正在尝试将其移植到已成功的 Windows 环境。因为我正试图尽快向人们推出 Windows 版本,所以我决定继续在 Windows 中进行开发,同时尝试添加新功能并解决已经存在数月的错误。最近尝试添加严重依赖三角函数的功能时,我发现所有 3 个三角函数,奇怪的是,无论我传递的参数如何,都返回相同的值 (1072693887)。可以想象,这会导致系统中出现一些相当奇怪的错误。

我已包含 math.h,据我所知,没有其他文件包含此函数。 (也许有一个调试器命令可以找到定义符号的位置?我找不到任何这样的东西,但也许我错过了一些东西。)我试过在其他地方询问并在谷歌上搜索,但无济于事......

有没有其他人听说过这个问题,或者知道如何解决它?

【问题讨论】:

  • 显示代码怎么样?
  • 你传递的数字是什么意思?

标签: c++ trigonometry cmath


【解决方案1】:

编辑:这个答案不相关。见 cmets。


这可能是由于数值不稳定。

当您将如此大的值传递给 sin()cos() 或任何周期性触发函数时,您必须记住 2*pi 的隐含模数。

如果您使用float,那么1072693887 的不确定性远大于2*pi。因此,无论你得到什么结果都是垃圾。

我们需要查看一些代码才能准确了解发生了什么。

编辑:这是一个插图:

sin(1072693886) =  0.6783204666
sin(1072693887) = -0.2517863119
sin(1072693888) = -0.9504019164

但是如果数据类型是float,那么1072693887的不确定性就是+/- ~64...

【讨论】:

  • 也许我应该更清楚...如果我输入一个值,比如 PI/3(该值应该是 3 的平方根,或大约 0.866),我得到 1072693886作为 trig 函数的返回值。
  • 那么这听起来像是您的代码中的一个明显错误。发布您的代码,以便我们查看。否则,我们将无法提供帮助。
【解决方案2】:

1072693887 是十六进制的 3FF207FF,代表 IEEE 单精度浮点的 1.8908690。您确定您的问题不只是一个表示问题,即您将结果转换或查看为整数吗?

【讨论】:

  • 我只知道 GDB 告诉我它的结果是 1072693887,它发生在我的所有 3 个三角函数中(并且所有三个函数的 arc 版本都只返回 -1072693887)无论我传递什么参数。即使你说的是真的,它似乎仍然是一个明显的错误。
  • 所以发布一个复制案例来展示你在做什么,否则你将得到的只是疯狂的猜测。 gnu 数学库经过了非常好的测试,并在数以百万计的应用程序中使用,结果受到最严格的审查,您发现错误的可能性非常小
【解决方案3】:

我所知道的是 GDB 告诉我它的结果是 1072693887,它发生在我的所有 3 个三角函数中(并且所有三个函数的弧版本都只返回 -1072693887),无论我使用什么参数通过。

可能是 GDB 问题。如果您只是手动将值打印到控制台会发生什么?

【讨论】:

  • 我希望我能回答这个问题......出于某种原因,即使 Code::Blocks 已将其设置为作为“控制台应用程序”运行,我对 std::cout 或printf 实际上出现了......
  • 那么你有比舍入问题更严重的问题。如果在main 的最后插入std::cin.peek(); 行会发生什么?
  • 嗯,控制台正在打开,在执行结束时我确实得到“按任意键继续”...但是无论我是从 Code::Blocks 中运行我的代码还是我只是打开 cmd.exe 并运行我的程序,无论哪种方式我都没有得到任何输出,尽管我的代码中有对 std::cout 的调用......而且这只发生在 Windows 上......
  • 好吧,好吧,我刚刚也在 Linux 上测试了它......显然这只是我的调试器的一个问题,因为我确实设法让我的 std::cout 调用在那里执行,并且实际上它确实告诉了我正确的数字...叹息无论如何,谢谢您的帮助...
【解决方案4】:

数学库很好。

您知道函数需要弧度作为输入吗?

例如:

double param = 90.0;
double rads = param * M_PI/180;
std::cout << std::fixed << "Angle : " << param << " sin : " << sin (rads) << " cos " << cos(rads);

输出:

Angle : 90.000000 sin : 1.000000 cos 0.000000-0.304811

【讨论】:

  • 这是真的,并且是许多(大多数?)“math.h 不起作用” 投诉的原因,但“症状”是随机的结果,不是一个一致的值。
  • 首先,我输入的是弧度。其次,即使我错误地输入了度数,sin 和 cos 的范围也是 1(即使 tan 的范围是无限的)。任意数的 sin 和任意数的 cos 仍不应返回 1072683887。
  • @drummerp 发布一个最小的代码示例来重现这一点。否则我们只能猜测。
  • 嗯...这很有趣。我尝试创建一个新项目以使用如下所示的单个文件对其进行测试:#include &lt;iostream&gt; #include &lt;math.h&gt; using namespace std; int main() { cout &lt;&lt; "The sin of 30 degrees is: " &lt;&lt; sin(30 * (M_PI / 180)) &lt;&lt; endl; return 0; } 事实上,它确实返回了 0.5。
  • @drummerp 所以这个bug就在别的地方:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多