メインコンテンツ

このページの内容は最新ではありません。最新版の英語を参照するには、ここをクリックします。

標準ライブラリの浮動小数点ルーチンの無効な使用

標準ライブラリ関数の間違った引数

説明

この欠陥は、標準ライブラリの浮動小数点関数および標準名前空間で無効な引数が使用された場合に発生します。この欠陥では以下が検出されます。

  • 丸めおよび絶対値の関数 (ceil()fabs()floor()fmod() など)

  • 分数および除算の関数 (fmod()modf())

  • 指数および対数の関数 (frexp()ldexp()sqrt()pow()exp()log()log10() など)

  • 三角関数 (cos()sin()tan()acos()asin()atan()atan2() など)

リスク

標準ライブラリの浮動小数点関数での定義域エラーにより、処理系定義の値が発生します。以降の計算で、この関数の戻り値を使用した場合、予期しない結果になる可能性があります。

修正方法

修正方法は欠陥の根本原因によって異なります。多くの場合、結果の詳細 (または Polyspace as You Code のソース コード ツールヒント) には欠陥につながる一連のイベントが表示されます。そのシーケンス内のどのイベントについても修正を実装できます。結果の詳細にイベント履歴が表示されない場合は、ソース コード内で右クリック オプションを使用して、欠陥に関連する変数のこれまでの参照を検索し、関連するイベントを検出できます。Polyspace デスクトップ ユーザー インターフェイスでの Bug Finder の結果の解釈またはPolyspace Access Web インターフェイスでの Bug Finder の結果の解釈 (Polyspace Access)も参照してください。

標準ライブラリの浮動小数点関数を使用する前に定義域エラーを処理することをお勧めします。たとえば、関数 acos を呼び出す前に、引数が [-1.0, 1.0] 内にあるかどうかをチェックしてエラーを処理します。

以下の修正例を参照してください。

問題を修正しない場合は、改めてレビューされないように結果またはコードにコメントを追加します。詳細は、以下を参照してください。

既定では、Bug Finder 解析は無限大と NaNs を認識しません。結果が無限大および NaNs になる演算には、欠陥としてフラグが設定される可能性があります。コードで無限大および NaN の値を処理するには、オプション [非有限の浮動小数点を検討] (-allow-non-finite-floats) を使用します。

チェッカーの拡張

カスタム ライブラリからの特定の値と関数の無効な使用を原因とする欠陥をチェックするには、このチェッカーを拡張してください。次に例を示します。

すべて展開する

#include <math.h>

double arccosine(void) {
    double degree = 5.0;
    return acos(degree);
}

acos への入力値は、区間 [-1,1] 内でなければなりません。この入力引数 degree はこの範囲外です。

修正 — 入力引数を変更

1 つの修正方法として、入力値を指定された範囲に適合するよう変更することができます。この例では、入力値を度からラジアンに変換することでこの欠陥を修正します。

#include <math.h>

double arccosine(void) {
    double degree = 5.0;
    double radian = degree * 3.14159 / 180.;
    return acos(radian);
}
#include <cmath>

void InvalidUse(double& val1, double& val2){
  int in = -5;
  int ratio = 0;
  //...
  val1 = std::sqrt(in);
  val2 = std::log(ratio);
}

std::sqrt() への入力値は、非負の値でなければなりません。Polyspace® は、負の入力引数 in の使用にフラグを設定します。std::log への入力値は、ゼロより大きくなければなりません。Polyspace は、ratio を使用した std::log の呼び出しにフラグを設定します。

修正 — コードをリファクタリング

1 つの修正方法として、ロジックを確認して、コードをリファクタリングします。たとえば、val1-5 の平方根を取るのではなく、5 の負の平方根を取るものと想定されている可能性があります。関数による ratio の定義が間違っている可能性もあります。

#include <cmath>
int getRatio(void);
void ValidUse(double& val1, double& val2){
  int in = 5;
  int ratio = getRatio();
  //...
  val1 = -1* std::sqrt(in);
  val2 = std::log(ratio);
}

結果情報

グループ: 数値
言語: C | C++
既定値: オン
コマンド ライン構文: FLOAT_STD_LIB
影響度: High

バージョン履歴

R2013b で導入

すべて展開する