はじめに
この実験では、Java で浮動小数点数が「非数」(NaN: Not a Number) であるかどうかをチェックする方法を学びます。Double.isNaN() メソッドを調べ、浮動小数点演算によって NaN 値がどのように生成されるかを理解し、NaN チェックの文脈で非浮動小数点数の入力をどのように扱うかを検討します。この実験の終わりまでに、Java プログラムで NaN 値を確実に検出し管理できるようになります。
Double.isNaN() を使ったチェック
このステップでは、Java で Double.isNaN() メソッドを使用して浮動小数点数が「非数」(NaN: Not a Number) であるかどうかをチェックする方法を学びます。
コンピュータの浮動小数点数は、時に NaN と呼ばれる特殊な値になることがあります。これは、計算結果が未定義であるか、標準的な数値として表現できない場合に起こります。たとえば、ゼロをゼロで割ったり、負の数の平方根を求めたりすると、NaN が結果として返されます。
プログラムで NaN 値を検出できることは重要です。なぜなら、NaN 値は通常の数値とは異なる振る舞いをするからです。たとえば、標準的な比較演算子 (==, <, >) を使用して NaN 値を他の任意の数値 (別の NaN でさえも) と比較すると、常に false になります。
Java では、NaN をチェックするための特定のメソッド Double.isNaN() が用意されています。このメソッドは double 型の値を入力として受け取り、その値が NaN であれば true を返し、そうでなければ false を返します。
Double.isNaN() の使い方を示すために、簡単な Java プログラムを作成しましょう。
WebIDE エディタで
HelloJava.javaファイルを開きます。既存のコードを以下のコードに置き換えます。
public class CheckNaN { public static void main(String[] args) { double result1 = 0.0 / 0.0; // This will result in NaN double result2 = 10.0 / 2.0; // This is a regular number System.out.println("Is result1 NaN? " + Double.isNaN(result1)); System.out.println("Is result2 NaN? " + Double.isNaN(result2)); } }このコードでは、以下のことを行っています。
- 2 つの
double型の変数result1とresult2を宣言しています。 result1には0.0 / 0.0の結果が代入されます。これは不定形であり、NaN が生成されます。result2には10.0 / 2.0の結果が代入されます。これは標準的な数値 (5.0) です。- その後、
Double.isNaN()を使用してresult1とresult2が NaN であるかどうかをチェックし、結果を出力します。
- 2 つの
ファイルを保存します (Ctrl+S または Cmd+S)。
ここで、新しいプログラムをコンパイルする必要があります。クラス名を
CheckNaNに変更したので、CheckNaN.javaをコンパイルする必要があります。ターミナルを開き、以下のコマンドを実行します。javac CheckNaN.javaコンパイルが成功すると、何も出力されないはずです。
最後に、コンパイルしたプログラムを実行します。
java CheckNaN以下のような出力が表示されるはずです。
Is result1 NaN? true Is result2 NaN? falseこの出力は、
Double.isNaN()がresult1を NaN として、result2を通常の数値として正しく識別したことを確認しています。
Java で NaN 値をチェックするには、Double.isNaN() を使用するのが正しく信頼性の高い方法です。直接比較 (== Double.NaN) に依存することはお勧めできません。なぜなら、前述のように NaN == NaN は false と評価されるからです。
浮動小数点演算でテストする
このステップでは、NaN をもたらす浮動小数点演算のさらなる例を探り、Double.isNaN() を使ってそれらをチェックする練習をします。どのような演算が NaN を生成するかを理解することは、潜在的なエラーを適切に処理する堅牢な Java コードを書くために重要です。
ゼロをゼロで割る以外にも、無限大や無効な数学関数を含む他の演算も NaN を生成することがあります。Java には正の無限大と負の無限大の特殊な表現 (Double.POSITIVE_INFINITY と Double.NEGATIVE_INFINITY) があります。
これらのケースのいくつかをテストするために、CheckNaN.java プログラムを修正しましょう。
WebIDE エディタで
CheckNaN.javaファイルを開きます。既存のコードを以下のコードに置き換えます。
public class CheckNaN { public static void main(String[] args) { double result1 = 0.0 / 0.0; // NaN double result2 = Math.sqrt(-1.0); // NaN (square root of a negative number) double result3 = Double.POSITIVE_INFINITY - Double.POSITIVE_INFINITY; // NaN double result4 = 10.0 / 0.0; // Positive Infinity double result5 = -10.0 / 0.0; // Negative Infinity double result6 = 5.0; // Regular number System.out.println("Is result1 NaN? " + Double.isNaN(result1)); System.out.println("Is result2 NaN? " + Double.isNaN(result2)); System.out.println("Is result3 NaN? " + Double.isNaN(result3)); System.out.println("Is result4 NaN? " + Double.isNaN(result4)); System.out.println("Is result5 NaN? " + Double.isNaN(result5)); System.out.println("Is result6 NaN? " + Double.isNaN(result6)); } }この更新されたコードでは、以下のことを行っています。
result1は依然として0.0 / 0.0です。result2はMath.sqrt(-1.0)を使用しています。これは実数において数学的に未定義であり、NaN をもたらします。result3は正の無限大から正の無限大を引いています。これも不定形であり、NaN をもたらします。result4とresult5はゼロで割る演算を示しています。これは正または負の無限大をもたらし、NaN ではありません。result6は比較用の単純な数値です。
ファイルを保存します (Ctrl+S または Cmd+S)。
ターミナルで修正したプログラムをコンパイルします。
javac CheckNaN.java再び、出力がないことはコンパイルが成功したことを示します。
プログラムを実行します。
java CheckNaN以下のような出力が表示されるはずです。
Is result1 NaN? true Is result2 NaN? true Is result3 NaN? true Is result4 NaN? false Is result5 NaN? false Is result6 NaN? falseこの出力は、
Double.isNaN()が NaN をもたらす 3 つの演算を正しく識別し、無限大の値と通常の数値を NaN ではないと正しく識別していることを示しています。
これらの異なる浮動小数点演算でテストすることで、NaN がいつ発生するか、およびプログラムでこれらのケースを処理するために Double.isNaN() をどのように使用するかをより深く理解することができます。
非浮動小数点入力の処理
前のステップでは、浮動小数点演算がどのようにして NaN をもたらすかに焦点を当てました。しかし、時には「テキスト」のような有効な数値ではない入力を受け取ることがあります。このような入力を浮動小数点数に変換しようとすると、問題が発生することがあります。
Double.isNaN() は浮動小数点計算の結果をチェックするためのものですが、最初の入力が数値として解析できないケースを処理することも重要です。Java には文字列を数値に解析するメソッドが用意されており、入力が無効な場合、これらのメソッドは例外をスローすることがあります。
ユーザー入力を double 型に解析し、解析された値が NaN であるかどうかをチェックする新しいプログラムを作成しましょう。
~/projectディレクトリにParseAndCheck.javaという名前の新しいファイルを作成します。これは、ファイルエクスプローラーで右クリックして「新しいファイル」を選択し、ParseAndCheck.javaと入力することで行えます。WebIDE エディタで
ParseAndCheck.javaファイルを開き、以下のコードを追加します。import java.util.Scanner; public class ParseAndCheck { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); System.out.print("Enter a floating-point number or an expression (e.g., 0.0/0.0): "); String input = scanner.nextLine(); try { double value = Double.parseDouble(input); if (Double.isNaN(value)) { System.out.println("The input resulted in NaN."); } else { System.out.println("The input is a valid number: " + value); } } catch (NumberFormatException e) { System.out.println("Invalid input: Could not parse as a number."); } finally { scanner.close(); } } }このコードを分解して説明しましょう。
Scannerクラスをインポートして、ユーザー入力を読み取ります。- ユーザーに文字列の入力を促します。
try-catchブロックを使用して、解析中の潜在的なエラーを処理します。Double.parseDouble(input)は、入力文字列をdouble型に変換しようとします。文字列が有効な数値形式でない場合 (例:"hello")、NumberFormatExceptionがスローされます。tryブロック内で、解析が成功した場合、Double.isNaN(value)を使用して、結果のdouble型が NaN であるかどうかをチェックします。catchブロックはNumberFormatExceptionをキャッチし、入力が解析できなかった場合にエラーメッセージを出力します。finallyブロックは、スキャナーが閉じられることを保証します。
ファイルを保存します (Ctrl+S または Cmd+S)。
ターミナルでプログラムをコンパイルします。
javac ParseAndCheck.javaプログラムを実行します。
java ParseAndCheckプログラムは入力を求めます。さまざまな値を入力してみましょう。
5.5を入力します。Enter a floating-point number or an expression (e.g., 0.0/0.0): 5.5 The input is a valid number: 5.50.0/0.0を入力します。Enter a floating-point number or an expression (e.g., 0.0/0.0): 0.0/0.0 Invalid input: Could not parse as a number.(注:
parseDoubleは数学的な式を直接評価することはできません。数値の文字列表現のみを解析します。)NaNを入力します。Enter a floating-point number or an expression (e.g., 0.0/0.0): NaN The input resulted in NaN.helloを入力します。Enter a floating-point number or an expression (e.g., 0.0/0.0): hello Invalid input: Could not parse as a number.
このステップでは、入力の解析と Double.isNaN() チェックを組み合わせて、有効な数値、文字列 "NaN"、無効な数値形式など、さまざまなタイプの入力を処理する方法を示しています。これは、外部ソースからの浮動小数点数を扱う際の潜在的な問題に対処するためのより完全なアプローチです。
まとめ
この実験では、Java で浮動小数点数が「非数 (Not a Number, NaN)」であるかどうかをチェックする方法を学びました。NaN は未定義または表現できない計算から生じる特殊な値であり、標準の比較演算子は NaN との比較では信頼性が低いことを発見しました。
具体的には、Double.isNaN() メソッドの使用に焦点を当てました。これは Java で NaN 値を正確に検出するための標準的かつ推奨される方法です。NaN を生成する浮動小数点演算や通常の数値結果を伴う例を用いて、その使い方を実証しました。



