【问题标题】:Precision issues with Visual Studio 2010Visual Studio 2010 的精度问题
【发布时间】:2025-11-25 23:05:02
【问题描述】:

我有一个用 Microsoft Visual C++ 6.0 编写的应用程序。现在我使用 C# 在 Visual Studio 2010 中重写了应用程序,但由于精度问题,结果不匹配。以下是此类精度问题之一。

float a = 1.0f;

float b = 3.0f;

float c = a / b;

这是在 Visual Studio 2010 中运行时的 C# 代码,给出 c 值 = 0.333333343

但同样的代码,在值定义中的值之后删除 f,当在 Visual C++ 6.0 上运行时,c 值 = 0.333333

任何人都可以整理并解释在 Visual Studio 和 Visual C++ 6.0 中 c 具有相同值的方法吗??


实际上这些值是从监视窗口中获取的。我开始知道不同版本的视觉工作室可能在浮点格式表示上有所不同。因此 watch 中的值可能没有用。这就是为什么我在两个 Visual Studio 版本中都打印了这些值的原因,结果如下。 使用 Visual Studio 6.0 使用 Visual C++ 语言,它是 0.333333(六个 3)

但使用 C# 语言的 Visual Studio 10 为 0.3333333(七个 3)

那么任何人都可以帮助我使我的 C# 程序产生与 Visual C++ 相同的结果吗??? (即如何进行浮动操作以在两个版本上产生相同的结果???)

【问题讨论】:

  • 您如何看待这些价值观?我很确定内部表示是相同的(除非我弄错了并且 C# 在幕后使用 double),但是向用户显示数字的方法不同,因此您可以简单地查看不同的显示默认值.
  • @MrLister C# 4.0 规范在第 4.1.6 节中说,对浮点数的二进制操作“使用 至少 float 范围和精度执行”(强调添加) .所以幕后的精度是实现定义的。 .NET Framework 很可能在幕后使用双精度。

标签: c# visual-studio-2010 visual-c++-6 floating-point-precision


【解决方案1】:

鉴于精确值是 0.3 循环,它们都不是“正确的” - 如果您尝试匹配二进制浮点计算的精确结果,那么开始通常不是一个好主意由于他们的工作方式。 (有关更多信息,请参阅我在 binary floating point in .NET 上的文章。)

可能您一开始就不应该使用二进制浮点数(例如,如果您的值代表精确的、人为的金额,例如金钱)。或者,您可能应该只对特定容差进行相等比较。

可能 C# 和 C 产生完全相同的位模式 - 但您会看到不同的结果,因为这些值是如何格式化的。同样,我不会使用数字的文本表示进行比较。

【讨论】:

  • 我已经打印了这两个值,Visual C++ 给出 0.333333(六个 3),而 C# 给出 0.3333333(七个 3)。这意味着其中存在错误。如何使 Visual C++ 6.0 和 Visual Studio 10 with C# 产生相同的结果??
  • @Mahesh:不,这并不意味着有错误。我怀疑这只是每个案例中涉及的文本格式。
【解决方案2】:

C# 只是显示更少的小数位。 0.333333343 四舍五入到六位有效数字是0.333333c 的基础价值是相同的。

当然,如果你想要更精确,你总是可以使用double变量。

【讨论】:

    【解决方案3】:

    C# 浮点可以由floatdouble 类型处理。 float 类型的精度为 7 位,double 的精度为 16。

    我相信 C++ 标准精度约为 16 位(平均为 15.9!)。

    在任何情况下,两种表示在算术上都不正确,因为 1/3 是 0.333 重复出现。

    我认为这只是您所看到的值的表示形式(请注意,调试器会将值转换为字符串以进行显示。如果您检查每个内存位置,您可能会发现这些值是一样的。

    【讨论】:

      【解决方案4】:

      快速检查表明,是的,数字完全相同。因此,您的问题的答案是,当您想要相同的输出时,您需要做的就是确保显示方法兼容。
      例如,C 中的 printf("%9.7f", result) 和 C# 中的 string.Format("{0:0.0000000}", result)。就是这样。

      【讨论】: