メインコンテンツ

CERT C: Rule FLP36-C

Preserve precision when converting integral values to floating-point type

説明

ルール定義

整数型から浮動小数点型に変換するときに精度を保持します。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; //Noncompliant
  printf("%ld\n", (big - (long int)approx));
  return 0;
}

この例では、long int 型の変数 bigfloat に変換されています。

修正 — より大きな浮動小数点型を使用

1 つの修正方法として、float ではなく double データ型に変換します。

#include <stdio.h>

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

チェック情報

グループ: Rule 05.浮動小数点 (FLP)

バージョン履歴

R2019a で導入


1 This software has been created by MathWorks incorporating portions of: the “SEI CERT-C Website,” © 2017 Carnegie Mellon University, the SEI CERT-C++ Web site © 2017 Carnegie Mellon University, ”SEI CERT C Coding Standard – Rules for Developing safe, Reliable and Secure systems – 2016 Edition,” © 2016 Carnegie Mellon University, and “SEI CERT C++ Coding Standard – Rules for Developing safe, Reliable and Secure systems in C++ – 2016 Edition” © 2016 Carnegie Mellon University, with special permission from its Software Engineering Institute.

ANY MATERIAL OF CARNEGIE MELLON UNIVERSITY AND/OR ITS SOFTWARE ENGINEERING INSTITUTE CONTAINED HEREIN IS FURNISHED ON AN "AS-IS" BASIS. CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY KIND, EITHER EXPRESSED OR IMPLIED, AS TO ANY MATTER INCLUDING, BUT NOT LIMITED TO, WARRANTY OF FITNESS FOR PURPOSE OR MERCHANTABILITY, EXCLUSIVITY, OR RESULTS OBTAINED FROM USE OF THE MATERIAL. CARNEGIE MELLON UNIVERSITY DOES NOT MAKE ANY WARRANTY OF ANY KIND WITH RESPECT TO FREEDOM FROM PATENT, TRADEMARK, OR COPYRIGHT INFRINGEMENT.

This software and associated documentation has not been reviewed nor is it endorsed by Carnegie Mellon University or its Software Engineering Institute.