gpt4 book ai didi

visual-studio-2008 - Visual Studio 中的错误浮点处理?

转载 作者:行者123 更新时间:2023-12-04 21:49:36 27 4
gpt4 key购买 nike

最后有更新!

我有一个小故事。

我想在由 MS Visual Studio 2008 编译的 C 程序(在 64 位 PC 上运行 Windows 7)中计算机器 epsilon(最大 epsilon > 0 满足条件 1.0 + epsilon = 1.0)。因为我知道 double 和 float 有不同的精度,所以我想看看两者的答案。出于这个原因,我构建了以下程序:

#include <stdio.h>
typedef double float_type;
int main()
{
float_type eps = 1.0;
while ((float_type) 1.0 + eps / (float_type) 2.0 > (float_type) 1.0)
eps = eps / (float_type) 2.0;
printf("%g\n", eps);
return 0;
}

我很惊讶地看到它对 double 和 float 两种类型都给出了相同的答案:2.22045e-16。这很奇怪,因为 double 占用的内存比 float 多两倍,而且应该更精确。之后我查看了 Wikipedia并从那里获取示例代码:
    #include <stdio.h>
int main(int argc, char **argv)
{
float machEps = 1.0f;
do {
machEps /= 2.0f;
} while ((float)(1.0 + (machEps/2.0)) != 1.0);
printf( "\nCalculated Machine epsilon: %G\n", machEps );
return 0;
}

当它正常工作时,我更加惊讶!在尝试理解这两个程序之间的根本区别之后,我发现了以下事实:如果我将循环条件更改为
  while ((float_type) (1.0 + eps / (float_type) 2.0) > (float_type) 1.0)

嗯,你会说这是个谜。哦,真正的奥秘在于以下。相比:
  while ((float) (1.0 + eps / 2.0f) > 1.0f) 

给出了正确答案(1.19209e-07)和
  while ((float) (1.0f + eps / 2.0f) > 1.0f)

这给出了对于 float 不正确而对于 double 正确的答案(2.22045e-16)。

事实上这是完全错误的,结果应该是相反的。这是因为默认情况下,编译器将像 1.0 这样的常量视为 double 值(根据标准),如果它存在于算术表达式中,则所有其他操作数都被提升为 double 值。相反,当我编写 1.0f 时,所有操作数都是浮点数,不应进行任何提升。然而我得到了完全不同的结果。

在所有这些测试之后,我尝试使用 gcc 在 Linux 上编译运行程序。毫不奇怪,它打印的正是我所期望的(正确答案)。所以我现在猜测这是 Visual Studio 的错误。为了让大家开怀大笑(如果有人看过我的帖子直到那一刻有什么值得怀疑的^_^)我再给你一个比较:
float c = 1.0;
while ((float) (c + eps / 2.0f) > 1.0f)

这在 VS 中不能正常工作,但是...
const float c = 1.0;

给出正确答案 1.19209e-07。

请有人告诉我问题的根源是否是错误的 VS 2008 编译器(你能确认你的机器上的错误吗?)。如果您在较新版本中测试此案例,我也将不胜感激:MS VS 2010。谢谢。

更新。
使用 MS Visual Studio 2013 时,我提到的第一个程序可以正常工作而没有意外结果——它为 float 和 double 提供了适当的答案。我用所有浮点模型(精确、严格和快速)检查了这一点,但没有任何改变。因此,在这种情况下,VS 2008 似乎确实存在问题。

最佳答案

默认情况下,Visual Studio 的浮点设置设置为“精确”。这意味着它将尝试使结果尽可能精确。这样做的副作用之一是中间体被提升为 double 。

虽然我没有查看您发布的每一段代码,但我怀疑问题出在这里:

(float) (c + eps / 2.0f)
c + eps / 2.0f使用 double 完成。 3 个操作数中的每一个都被提升为 double ,并且整个表达式都被这样评估。只有在您施放它时,它才会向下舍入为浮点数。

如果您将浮点模式设置为“严格”,它应该会按您的预期工作。

关于visual-studio-2008 - Visual Studio 中的错误浮点处理?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7406174/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com