主要内容

使用相等运算符 (BAD_FLOAT_OP) 进行浮点比较

R2026b

浮点变量的不精确比较

描述

当您对浮点数使用相等 (==) 或不相等 (!=) 运算时,会出现此缺陷。

在以下情况下,Polyspace® 不会对浮点数的相等或不相等运算引发缺陷:

  • 比较在两个浮点常量之间进行。

        float flt = 1.0;
        if (flt == 1.1)
  • 比较在一个常量和一个只能取有限、合理少量值的变量之间进行。

    float x;
    
    int rand = random(); 
    switch(rand) { 
    case 1: x = 0.0; break; 
    case 2: x = 1.3; break; 
    case 3: x = 1.7; break; 
    case 4: x = 2.0; break; 
    default: x = 3.5; break; }
    …
    if (x==1.3) 
  • 比较在仅包含整数值的浮点表达式之间进行。

    float x = 0.0;
    for (x=0.0;x!=100.0;x+=1.0) {
    …
    if (random) break;
    }
    
    if (3*x+4==2*x-1)
    …
    if (3*x+4 == 1.3)
  • 其中一个操作数是 0.0,除非您使用选项标志 -detect-bad-float-op-on-zero。

    /* Defect detected when
    you use the option flag */
    
    if (x==0.0f) 

    如果您正在从 Polyspace 平台用户界面运行分析,可以通过工程配置应用此选项。为此,请导航到静态分析选项卡,选择高级节点,然后在其他字段中输入此选项。请参阅其他。

    在命令行中,将该标志添加到分析命令。

    polyspace-bug-finder -sources filename ^
    -checkers BAD_FLOAT_OP -detect-bad-float-op-on-zero

风险

检查两个浮点值是否相等或不相等可能会返回意外结果,因为浮点表示是不精确的,涉及舍入误差。

修复

不要检查浮点值是否相等:

if (val1 == val2)
而是检查它们的差是否小于预定义的容差值(例如 float.h 中定义的值 FLT_EPSILON):
#include <float.h>
if(fabs(val1-val2) < FLT_EPSILON)

请参阅下面的修复示例。

如果您不想修复该问题,可以在结果或代码中添加注释,以避免再次被审查。请参阅:

示例

全部展开

#include <stdio.h>
#include <math.h>
#include <float.h>

void func(void)
{
    float f;
    for (f = 1.0; f != 2.0; f = f + 0.1)    
        (void)printf("Value: %f\n", f);
}

在此函数中,for 循环通过测试 f 与数字 2.0 是否不相等来作为停止机制。由于浮点表示的不精确性,迭代次数难以确定,甚至可能是无限循环。

更正 - 更改运算符

一种可能的更正方法是使用不那么严格的运算符。例如,>= 或 <= 这样的不相等运算符。

#include <stdio.h>
#include <math.h>
#include <float.h>

void func(void)
{
    float f;
    for (f = 1.0; f <= 2.0; f = f + 0.1)    
        (void)printf("Value: %f\n", f);
}

结果信息

组:编程
语言:C | C++
默认值:关闭
命令行语法:BAD_FLOAT_OP
影响:中
PQL 名称:std.defects.BAD_FLOAT_OP

版本历史记录

在 R2013b 中推出