CERT C: Rec. FLP02-C

Избегайте использования чисел с плавающей запятой, когда точное вычисление будет необходимо

Описание

Управляйте определением

Избегайте использования чисел с плавающей запятой, когда точное вычисление будет необходимо. [1]

Примеры

развернуть все

Описание

Сравнение с плавающей точкой с операторами равенства происходит, когда вы используете равенство (==) или операция (!=) неравенства с числами с плавающей запятой.

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) 

    Если при запуске анализ через пользовательский интерфейс, можно ввести эту опцию в поле Other под узлом Advanced Settings на панели Configuration. Смотрите Other.

    В командной строке добавьте флаг в свою аналитическую команду.

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

Риск

Проверка равенство или неравенство двух значений с плавающей точкой может возвратить неожиданные результаты, потому что представления с плавающей точкой неточны и включают погрешности округления.

Фиксация

Вместо того, чтобы проверять на равенство значений с плавающей точкой:

if (val1 == val2)
проверяйте, являются ли их различием меньше, чем предопределенное значение допуска (например, значение FLT_EPSILON, заданный в float.h):
#include <float.h>
if(fabs(val1-val2) < FLT_EPSILON)

Смотрите примеры мер ниже.

Если вы не хотите устранять проблему, добавьте комментарии в свой результат или код, чтобы избежать другого анализа. Смотрите Результаты Polyspace Адреса Через Исправления ошибок или Комментарии.

Пример - пускает в ход неравенство в for - цикл

#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);
}

Проверяйте информацию

Группа: Rec. 05. Плавающая точка (FLP)

Введенный в R2019a


[1]  Это программное обеспечение было создано MathWorks, включающим фрагменты: “Веб-сайт SEI CERT-C”, © 2017 Carnegie Mellon University, веб-сайт SEI CERT-C © 2017 Carnegie Mellon University”, CERT SEI C Кодирование Стандарта – Правил для Разработки безопасных, Надежных и Защищенных систем – 2 016 Выпусков”, © 2016 Carnegie Mellon University, and “CERT SEI Стандарт Кодирования C++ – Правил для Разработки безопасных, Надежных и Защищенных систем на C++ – 2 016 Выпусков” © 2016 Carnegie Mellon University, со специальным разрешением от его Института программной инженерии.

ЛЮБОЙ МАТЕРИАЛ УНИВЕРСИТЕТА КАРНЕГИ-МЕЛЛОН И/ИЛИ ЕГО ИНСТИТУТА ПРОГРАММНОЙ ИНЖЕНЕРИИ СОДЕРЖАЛ, ЗДЕСЬ ПРЕДОСТАВЛЯЕТСЯ НА ОСНОВЕ "ASIS". УНИВЕРСИТЕТ КАРНЕГИ-МЕЛЛОН НЕ ДАЕТ ГАРАНТИЙ НИКАКОГО ВИДА, ИЛИ ВЫРАЗИЛ ИЛИ ПОДРАЗУМЕВАЛ, ОТНОСИТЕЛЬНО ЛЮБОГО ВОПРОСА ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИЛ, ГАРАНТИЯ ПРИГОДНОСТИ ДЛЯ ЦЕЛИ ИЛИ ВЫСОКОГО СПРОСА, ИСКЛЮЧИТЕЛЬНОСТИ, ИЛИ ЗАКАНЧИВАЕТСЯ ПОЛУЧЕННЫЙ ИЗ ИСПОЛЬЗОВАНИЯ МАТЕРИАЛА. УНИВЕРСИТЕТ КАРНЕГИ-МЕЛЛОН НЕ ДАЕТ ГАРАНТИИ НИКАКОГО ВИДА ОТНОСИТЕЛЬНО СВОБОДЫ ОТ ПАТЕНТА, ТОВАРНОГО ЗНАКА ИЛИ НАРУШЕНИЯ АВТОРСКОГО ПРАВА.

Это программное обеспечение и сопоставленная документация не были рассмотрены, ни являются подтвержденным Университетом Карнеги-Меллон или его Институтом программной инженерии.