0

Math.Atan2 或 C# 中的类实例问题类似的问题, 并 在给出错误结果的情况下添加两个双精度

这是简单的线条:

public static String DegreeToRadianStr(Double degree)
    {
        Double piBy180 = (Math.PI / 180);

        Double Val = (piBy180 * degree);  // Here it is giving wrong value
    }

piBy180 * degree = -3.1415926535897931 但 Val = -3.1415927410125732

alt text http://www.imagechicken.com/uploads/1262936639009840000.jpg 我真的不知道该怎么办..请就此提出一些问题,以便我指出哪里出了问题。

令人惊讶的是 piBy180 保持正确的值。

其他功能也发生了同样的事情,但是我如何操作以获得正确的值。

我正在使用 MS Visual Studio 的 C#.net SP1。

4

4 回答 4

3

如果您告诉我们的价值,那将有所帮助,degree然后我们可以尝试重现该问题...

三件事:

  • 您应该预料到浮点运算会出现一定程度的错误。我不会期望这么多,但不要期望看到一个确切的值。
  • 字符串转换通常不会向您显示确切的值。我有一个文件——DoubleConverter.cs——有一个ToExactString可以帮助诊断这类事情的方法。
  • 您的应用程序是否使用 DirectX?即使您的代码中有双精度数,这也可以更改处理器模式以有效地使用 32 位算术。在我看来,这似乎是问题的最可能原因,但这仍然只是一个猜测。

编辑:好的,听起来我猜对了,DirectX 可能是原因。您可以将CreateFlags.FpuPreserve传递给Device构造函数以避免它这样做。诚然,这将降低 DirectX 的性能 - 但这是您需要自己考虑的权衡。

于 2010-01-08T07:03:39.737 回答
2

这可能只是一个字符串格式问题。尝试添加该行:

Debug.Assert(Val == (piBy180 * degree), "WTF?");

分配后。它不应该失败,因为它们都是双精度数,并且对它们的算术运算应该产生相同的二进制值。

于 2010-01-08T06:56:05.987 回答
0

这似乎不可能。

piBy180 * degree 的值几乎可以正确计算,在第 17 位有效数字中相差不到 2 个单位。CPU 必须执行乘法来执行此操作,并且它以双精度正确地执行此操作,即使有人试图通过滥用 DirectX 调用来弄乱精度。

Val 的值在第 8 位有效数字处已经是错误的。Val 被声明为 double,它被分配了一个微秒前计算的 double 值,没有进一步的计算。

这是发布版本吗?我想知道 C# 是否可能像 C++ 那样省略了将最新值存储到 Val 中。在调试版本中会发生什么?

于 2010-01-08T07:50:40.357 回答
0

这可能只是一个舍入错误,但我不能确定。

查看这篇关于浮点运算的文章。它是为 fortran 编写的,但它仍然有用。 http://www.lahey.com/float.htm

于 2010-01-08T06:52:06.313 回答