双变量保持错误的值

时间:2010-01-08 06:48:10

标签: c# .net double multiplication

类似的问题 Math.Atan2 or class instance problem in C#add two double given wrong result

这是简单的界限:

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

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

piBy180 *度= -3.1415926535897931 但是Val = -3.1415927410125732

alt text http://www.imagechicken.com/uploads/1262936639009840000.jpg 我真的不知道该怎么做.. 请问一些有关这方面的问题,以便我可以指出它出错的地方。

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

同样的事情也发生在其他功能上,但有些我操纵得到正确的值。

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

4 个答案:

答案 0 :(得分:3)

如果您告诉我们degree的价值,那么我们可以尝试重现这个问题会有所帮助......

三件事:

  • 浮点运算应该会出现一定程度的误差。我不会期待这么多,但不要指望看到确切的价值。
  • 字符串转换通常不会显示确切的值。我有一个文件 - DoubleConverter.cs - 使用ToExactString方法可以帮助诊断此类事情。
  • 您的应用是否完全使用DirectX?即使你的代码中有双打,这也可以改变处理器模式以有效地使用32位算术。在我看来,这是问题的最可能原因,但它仍然只是猜测。
编辑:好的,所以听起来我猜对了,DirectX可能就是原因。您可以将CreateFlags.FpuPreserve传递给Device constructor以避免它执行此操作。这无疑会降低DirectX的性能 - 但这是你需要自己考虑的权衡。

答案 1 :(得分:2)

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

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

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

答案 2 :(得分:0)

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

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

答案 3 :(得分:0)

这似乎不太可能。

piBy180 *度的值几乎正确计算,在第17位有效数字中小于2个单位。 CPU必须执行乘法才能执行此操作,并且正确地以双精度执行此操作,即使有人试图通过滥用DirectX调用来破坏精度。

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

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