CERT C: Rec. FLP02-C

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

Описание

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

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

Реализация Polyspace

Это средство проверки проверяет на сравнение С плавающей точкой с операторами равенства.

Примеры

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

Проблема

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

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". УНИВЕРСИТЕТ КАРНЕГИ-МЕЛЛОН НЕ ДАЕТ ГАРАНТИЙ НИКАКОГО ВИДА, ИЛИ ОПИСАЛ ИЛИ ПОДРАЗУМЕВАЛ, ОТНОСИТЕЛЬНО ЛЮБОГО ВОПРОСА ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИЛ, ГАРАНТИЯ ПРИГОДНОСТИ ДЛЯ ЦЕЛИ ИЛИ ВЫСОКОГО СПРОСА, ИСКЛЮЧИТЕЛЬНОСТИ, ИЛИ ЗАКАНЧИВАЕТСЯ ПОЛУЧЕННЫЙ ИЗ ИСПОЛЬЗОВАНИЯ МАТЕРИАЛА. УНИВЕРСИТЕТ КАРНЕГИ-МЕЛЛОН НЕ ДАЕТ ГАРАНТИИ НИКАКОГО ВИДА ОТНОСИТЕЛЬНО СВОБОДЫ ОТ ПАТЕНТА, ТОВАРНОГО ЗНАКА ИЛИ НАРУШЕНИЯ АВТОРСКОГО ПРАВА.

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