JPCERT コーディネーションセンター

NUM09-J. 浮動小数点数型変数をループカウンタとして使用しない

NUM09-J. 浮動小数点数型変数をループカウンタとして使用しない

浮動小数点数型変数をループカウンタとして使用してはならない。精度に限界のあるIEEE 754浮動小数点数型は、次に示すように、すべての値を表現できるわけではない。

このルールにおいて「ループカウンタ」とは、dowhileforループの制御式として使われる比較式のオペランドである帰納変数のことである。「帰納変数」とは、ループの繰り返しごとに一定量増減する変数のこと [Aho 1986] で、(ループ内で実行される関数の中ではなく) ループ本体で直接変更されるものを指す。

このルールは「NUM04-J. 正確な計算が必要なときは浮動小数点数を使わない」の一部である。

違反コード

以下の違反コード例では浮動小数点数型変数をループカウンタとして使用している。0.1という小数は、float型でもdouble型でも厳密に表現することはできない。

for (float x = 0.1f; x <= 1.0f; x += 0.1f) {
  System.out.println(x);
}

0.1ffloat型で表現できる近似値に丸められるため、繰り返し処理でxに加算される実際の値は0.1よりもわずかに大きい。それゆえ、ループは9回だけ実行され、期待とは異なる結果を出力する。

適合コード

以下の適合コードではint型整数をループカウンタとして使用しており、期待した浮動小数点数が得られる。

for (int count = 1; count <= 10; count += 1) {
  float x = count/10.0f;
  System.out.println(x);
}
違反コード

以下の違反コードでは、浮動小数点数型変数をループカウンタとして用いてインクリメントしているが、与えられた精度では値が小さすぎて変化しない。

for (float x = 100000001.0f; x <= 100000010.0f; x += 1.0f) {
  /* ... */
}

このコードは無限にループする。

適合コード

以下の適合コードではint型変数をループカウンタとして使用し、その値を元に浮動小数点数を算出している。またdouble型を使い、求める値を表現するために十分な精度が得られることを保証している。さらに、FP-strictモードで実行すると、結果の可搬性が保証される (詳しくは「NUM53-J. どのプラットフォームでも一貫した浮動小数点数演算を行うために strictfp 修飾子を使う」を参照)。

for (int count = 1; count <= 10; count += 1) {
  double x = 100000000.0 + count;
  /* ... */
}
リスク評価

ループカウンタに浮動小数点数を使用すると、プログラムの予期せぬ動作につながる恐れがある。

ルール

深刻度

可能性

自動検出

自動修正

優先度

レベル

NUM09-J

不可

P4

L3

自動検出

浮動小数点数型ループカウンタの検出は容易である。

ツール バージョン チェッカー 説明
Klocwork

2025.2

JAVA.LOOP.CTR.FLOAT
Parasoft Jtest 2024.2 CERT.NUM09.FPLI Do not use floating point variables as loop indices
PVS-Studio

7.39

V6108
関連ガイドライン

SEI CERT C コーディングスタンダード

FLP30-C. 浮動小数点変数をループカウンタに使用しない

ISO/IEC TR 24772:2010

Floating-point Arithmetic [PLF]

参考文献
[Aho 1986]

[Bloch 2005]

Puzzle 34, "Down for the Count"

[JLS 2015]

§4.2.3, "Floating-Point Types, Formats, and Values"

[Seacord 2015] Image result for video icon NUM09-J. Do not use floating-point variables as loop counters LiveLesson
翻訳元

これは以下のページを翻訳したものです。

NUM09-J. Do not use floating-point variables as loop counters (revision 113)

Top へ

Topへ
最新情報(RSSメーリングリストTwitter