C 基础知识 : double variable not equal to double expression?

标签 c syntax floating-point expression floating-accuracy

我正在使用一个名为 indata 的 double 组(在堆中,使用 malloc 分配)和一个名为 sum 的本地 double 组。

我写了两个不同的函数来比较 indata 中的值,得到了不同的结果。最终我确定差异是由于一个函数在条件测试中使用表达式,而另一个函数在同一条件测试中使用局部变量。我希望这些是等效的。

我的函数 A 使用:

    if (indata[i]+indata[j] > max) hi++;

我的函数 B 使用:

    sum = indata[i]+indata[j];
    if (sum>max) hi++;

在遍历相同的数据集和 max 之后,我最终得到了不同的 hi 值,具体取决于我使用的是哪个函数。我相信函数 B 是正确的,而函数 A 具有误导性。同样,当我尝试下面的代码片段时

    sum = indata[i]+indata[j];
    if ((indata[i]+indata[j]) != sum) etc.

该条件将评估为真。

虽然我知道 float 不一定提供精确的表示,但为什么当作为表达式计算而不是存储在变量中时,这种不精确的表示会发生变化?推荐的最佳做法是始终在条件之前评估这样的双表达式吗?谢谢!

最佳答案

我怀疑您使用的是 32 位 x86,这是唯一受制于超精度 的常见架构。在 C 中,floatdouble 类型的表达式实际上被计算为 float_tdouble_t,它们与 floatdouble 反射(reflect)在 FLT_EVAL_METHOD 宏中。在 x86 的情况下,两者都被定义为 long double,因为 fpu 实际上不能以单精度或 double 执行算术运算。 (它有旨在允许这样做的模式位,但行为略有错误,因此不能使用。)

分配给 floatdouble 类型的对象是一种强制舍入并消除多余精度的方法,但您也可以只添加一个无偿强制转换(double) 如果您希望将其保留为没有赋值的表达式。

请注意,强制舍入到所需精度并不等同于以所需精度执行算术;而不是一个舍入步骤(在算术过程中)你现在有两个(在算术过程中,再次降低不需要的精度),并且在第一次舍入给你一个精确的中点的情况下,第二次舍入可以进入“错误的” ' 方向。这个问题通常被称为双舍入,对于某些类型的计算,它会使超额精度明显低于标称精度。

关于C 基础知识 : double variable not equal to double expression?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37626687/

相关文章:

c - Win32 GUI应用程序: how to get stderr messages into messagebox

C子进程没有收到SIGINT信号

Python C++ float 学表示错误

php - 为什么 PHP 会将 (int) ((0.1+0.7)*10) 的结果转换为 7,而不是 8?

go - 为什么在Golang中将1.0/3.0数字文字三倍相加得出恰好为1?

c - 如何在memmove后释放分配的指针

c - Lua - pcall "entry point"

haskell - 访问数据构造函数haskell中的类型字段

arrays - 如何将一组 Expr(表达式)传递给 Haxe 宏?

vim - 自定义语法着色 vim