メインコンテンツ

CERT C: Rec.FLP00-C

浮動小数点数の制限事項を理解する

説明

ルール定義

浮動小数点数の制限事項を理解します。1

Polyspace 実装

ルール チェッカーは、"浮動小数点オペランドの統合" をチェックします。

すべて展開する

問題

浮動小数点オペランドの統合は、加算または減算演算の一方のオペランドが、他方のオペランドに比べて "常に" 無視できるほど小さい場合に発生します。その結果、演算の結果は大きなオペランドの値と必ず等しくなり、この演算が冗長になります。

リスク

冗長な演算はプロセッサの実行サイクルを浪費します。

浮動小数点オペランドの統合は、コード内のどこかに設計上の問題があることを示している場合があります。オペランドの 1 つの範囲が開発者の想定では異なっており、その演算が冗長になるとは開発者は想定していなかった可能性があります。そのオペランドの範囲が開発者の想定範囲と異なっている理由は、コード内のどこかに問題があるためです。

修正方法

オペランドの範囲が想定した範囲かどうかを確認します。範囲を確認するには、その演算にカーソルを置きます。

  • 範囲が想定どおりであれば、冗長な演算になる理由を正当化します。たとえば、コードの一部しか作成しておらず、まだ作成していないコードで一方または両方のオペランドが他の値になると予想される場合です。

    冗長な演算を正当化できない場合は、それを削除します。

  • 範囲が想定どおりでない場合、その範囲がコード内のどこで設定されるかをトレースバックします。トレースバックを開始するには、コード内でそのオペランドのインスタンスを検索します。そのオペランドの前のインスタンスを参照し、予期しない範囲を設定している箇所を判断します。

一方のオペランドが他方のオペランドと比べて非常に小さな値になるタイミングを判断するため、欠陥では IEEE® 754 規格に基づくルールを使用します。欠陥を修正するには、実際のルールを使用する代わりに、小さい値のオペランドと大きい値のオペランドの比率が少なくとも一部の値で 2p-1 よりも小さくならなければならないというヒューリスティックを使用します。ここで、p は、32 ビット精度では 24、64 ビット精度では 53 に相当します。この精度を決めるため、欠陥ではターゲット プロセッサ タイプ (-target)の指定を使用します。

例 - 一方のオペランドが他方のオペランドよりも無視できるほど小さい加算
#include <stdlib.h>

float get_signal(void);
void do_operation(float);

float input_signal1(void) {
    float temp = get_signal();
    if(temp > 0. && temp < 1e-30)
        return temp;
    else {
       /* Reject value */    
       exit(EXIT_FAILURE);
    }
}

float input_signal2(void) {
    float temp = get_signal();
    if(temp > 1.)
        return temp;
    else {
       /* Reject value */    
       exit(EXIT_FAILURE);
    }
}

void main() {
    float signal1 = input_signal1();
    float signal2 = input_signal2();
    float super_signal = signal1 + signal2; //Noncompliant
    do_operation(super_signal);
}

この例では、オペランド signal1(0,1e-30) の範囲内に収まっていても、signal21 より大きいため、加算で欠陥が現れます。

修正 - 冗長な演算を削除

考えられる 1 つの修正方法として、冗長な加算演算を削除します。修正した次のコードでは、オペランド signal2 およびそれに関連するコードも検討対象から削除されています。

#include <stdlib.h>

float get_signal(void);
void do_operation(float);

float input_signal1(void) {
    float temp = get_signal();
    if(temp > 0. && temp < 1e-30)
        return temp;
    else {
       /* Reject value */    
       exit(EXIT_FAILURE);
    }
}

void main() {
    float signal1 = input_signal1();
    do_operation(signal1);
}
修正 — オペランドの範囲を検証

別の修正方法として、オペランドの範囲が想定どおりかどうかを確認します。たとえば、オペランドの範囲のいずれかが無視できないほど小さくなるとは想定されない場合は、範囲を小さくしている問題を修正します。修正した次のコードでは、signal2 の範囲を (0,1e-2) に限定して指定しているため、signal1 と比べて "常に" 無視できるほど小さくなりません。

#include <stdlib.h>

float get_signal(void);
void do_operation(float);

float input_signal1(void) {
    float temp = get_signal();
    if(temp > 0. && temp < 1e-2)
        return temp;
    else {
       /* Reject value */    
       exit(EXIT_FAILURE);
    }
}

float input_signal2(void) {
    float temp = get_signal();
    if(temp > 1.)
        return temp;
    else {
       /* Reject value */    
       exit(EXIT_FAILURE);
    }
}

void main() {
    float signal1 = input_signal1();
    float signal2 = input_signal2();
    float super_signal = signal1 + signal2;
    do_operation(super_signal);
}

チェック情報

グループ: Rec.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.