CERT C: Rule FLP36-C

Сохраните точность при преобразовании интегральных значений в тип с плавающей точкой

Описание

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

Сохраните точность при преобразовании интегральных значений в тип с плавающей точкой. [1]

Реализация Polyspace

Это средство проверки проверяет на потерю Точности в целом числе, чтобы пустить в ход преобразование.

Примеры

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

Проблема

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

Например, long int значение 1234567890L является слишком большим для переменной типа float .

Риск

Если тип с плавающей точкой не может представлять целочисленное значение, поведение не определено (см. стандарт C11, 6.3.1.4, абзац 2). Например, младшие значащие биты значения переменных могут быть пропущены, ведя к неожиданным результатам.

Фиксация

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

Например, если float тип данных не может представлять целочисленное значение, использовать double тип данных вместо этого.

Когда запись функции, которая преобразует целое число в тип с плавающей точкой перед преобразованием, проверяет, может ли целочисленное значение быть представлено в типе с плавающей точкой. Например, DBL_MANT_DIG * log2(FLT_RADIX) представляет количество основы 2 цифры в типе double. Перед преобразованием в тип double, проверяйте, больше ли этот номер или равен с точностью целого числа, которое вы преобразуете. Определить точность целочисленного num, используйте этот код:

 size_t precision = 0;
 while (num != 0) {
    if (num % 2 == 1) {
      precision++;
    }
    num >>= 1;
 }

Некоторые реализации обеспечивают встроенную функцию, чтобы определить точность целого числа. Например, GCC обеспечивает функциональный __builtin_popcount.

Пример - преобразование большого целого числа к типу с плавающей точкой

#include <stdio.h>

int main(void) {
  long int big = 1234567890L;
  float approx = big;
  printf("%ld\n", (big - (long int)approx));
  return 0;
}

В этом примере, long int переменная big преобразован в float.

Коррекция — использует более широкий тип с плавающей точкой

Одна возможная коррекция должна преобразовать в double тип данных вместо float.

#include <stdio.h>

int main(void) {
  long int big = 1234567890L;
  double approx = big;
  printf("%ld\n", (big - (long int)approx));
  return 0;
}

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

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

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