CodeGym /コース /JAVA 25 SELF /小数と double 型の入門

小数と double 型の入門

JAVA 25 SELF
レベル 6 , レッスン 2
使用可能

1. 小数

たとえば、最も簡単な電卓を書こうとする場合や、計算が必要なあらゆるプログラム(お金の単純な集計から高度な物理シミュレーションまで)でも同じです。現実の世界では、すべてが整数というわけではありません。これはどうしようもありません。

では、新しいデータ型を身につけましょう!

プログラミングでは、小数は 実数、あるいは 浮動小数点数floating-point)とも呼ばれます。Java を含む多くの言語では、整数だけでなく「小数」の値、たとえば 3.14-28.572.718281828 などを保持するために使います。

浮動小数点数には主に2種類があります:

表すもの 値の範囲(概算) 精度 典型サイズ
float
数値 ±1.5 × 10-45 ... ±3.4 × 1038 小数点以下約7桁 4 バイト
double
数値 ±5.0 × 10-324 ... ±1.7 × 10308 小数点以下約15–16桁 8 バイト

float

float 型という名前は floating-point number(浮動小数点数)に由来します。数学における実数には特定の性質がありますが、コンピューターには多くの制約があります。そのため、Java の小数を「実数」と呼ぶのは厳密には適切ではありません。ここでは「浮動小数点数」という呼び名を使います。

float 型は通常、有効数字 7 桁(例: 0.1234567)と 10 の指数部を持ち、メモリを 4 バイト使用します。正確な計算には不十分なため、一般には倍精度の利用が主流です。

double

double 型という名前は 倍精度(double precision)に由来します。メモリでは 8 バイト(float の 2 倍)を占め、有効数字は最大 15 桁まで保持できます: 0.123456789012345。小数の計算の大半には十分なので、Java では double が小数を扱う基本型です。

この講義では主に double 型に焦点を当てます。いわゆる「一般的な」小数には既定で double を使うことが推奨されます。ただしこの後で float 型についても取り上げます。

2. double 型変数の宣言と初期化

基本は int と同じですが、ここでは double を使います。

// 変数を宣言し、円周率の値を代入する
double pi = 3.1415926;

// 初期化なしで宣言だけも可能
double averageSalary;
averageSalary = 91234.56;

// 計算もできる!
double pizzaPieces = 8;
double friends = 3;
double piecesPerFriend = pizzaPieces / friends; // 2.666...(2 ではない)

構文上の注意点:

  • 小数点の区切りには ピリオド3.14)を使います。カンマを使うとコンパイルエラーになります!
  • 厳密には、double d = 3; と書いてもエラーにはなりません。型は自動的に変換され(整数は損失なく「浮動小数点数」に変わります)。

3. Scanner を使った小数の入出力

まずは小数を出力してみましょう:

double amount = 42.75;
System.out.println(amount); // 出力: 42.75

問題ありません。では、文字列を足すとどうなるでしょうか:

System.out.println("あなたの口座残高: " + amount + " ユーロ。"); // 出力: あなたの口座残高: 42.75 ユーロ。

キーボードからの入力

double を入力するには、Scanner クラスの専用メソッド console.nextDouble() を使います。

Scanner console = new Scanner(System.in);

System.out.println("外の気温を入力してください:");
double temperature = console.nextDouble(); // そのまま double を読み込む

System.out.println("現在の外気温: " + temperature + " 度です。");

4. double の実践: 算術演算

おなじみの演算(+-*/)は、int と同様に使えます:

double distance = 100.5;
double time = 2.0;
double speed = distance / time; // 50.25

System.out.println("平均速度: " + speed); // 平均速度: 50.25

基本はこれだけです。唯一の違いは、オペランドの少なくとも一方が double の場合、除算の結果は常に小数になることです。

int と比較

int a = 5, b = 2;
System.out.println(a / b); // 2(端数は切り捨て)

double aa = 5, bb = 2;
System.out.println(aa / bb); // 2.5

5. double を扱うときの典型的な誤りや「癖」

入力の変換エラー

典型的な状況です。ユーザーは 3,14 を入力しますが、プログラムは 3.14 を期待しています。Java の Scanner.nextDouble() は現在の ロケールに依存します。ロシア語/ドイツ語のロケールではカンマが許容され、英語のロケールではピリオドが必要です。必要に応じて Scanner のロケールを設定するか、文字列として読み込んで手動でパースしてください。

// Locale.US では、入力が「3,14」だと問題になります
double value = console.nextDouble();

コンピューターにおける「不正確さ」の問題

ここで初心者はたいてい少し戸惑います:

double x = 0.1 + 0.2;
System.out.println(x); // えっ… 0.30000000000000004

これは、コンピューター内部での小数表現の「不思議」に遭遇したということです。多くの数値は 2 進法では厳密に表現できません。多くのアプリケーションでは通常それほど問題になりませんが、金融や精密な科学計算では注意が必要です。

6. 重要: doubleint — 暗黙的変換と明示的キャスト

整数と小数を足したり、intdouble に代入しても、エラーにはなりません:

int i = 2;
double d = i; // 問題なし!
System.out.println(d); // 2

double dd = 3.7;
int ii = (int) dd; // double から int へは明示的にキャストが必要!
System.out.println(ii); // 3(小数部分は切り捨て)

よくある驚き: なぜキャストしたら小数部分が消えるのか? それは int 型が小数を保持できないからです(小数点以下はすべて切り捨てられます)。

doubleint に変換する方法や演算子 (int) の詳細は、次回の講義で扱います。

7. フォーマット付き出力: きれいに double を表示する

既定のままだと、double が余分な桁まで表示されることがあります。出力を整形しましょう:

double temp = 23.56789;
System.out.println(temp); // 23.56789

// 小数点以下 2 桁
System.out.println(String.format("%.2f", temp)); // 23.57

// 小数点以下 1 桁
System.out.println(String.format("%.1f%n", temp)); // 23.6
フォーマット 結果 説明
"%.2f"
23.57 小数点以下 2 桁の数
"%.1f"
23.6 小数点以下 1 桁の数

8. floatdouble のよくあるミス

エラー1: double を float に暗黙変換しようとする

float f = 1.23; // エラー!

コンパイラはこう警告します。「doublefloat に入れようとしています。精度を失う可能性があります!」 いつも接尾辞 f を付けましょう。

エラー2: int 同士の除算は int の結果であることを忘れる

int a = 7, b = 2;
double result = a / b; // 3.0(3.5 ではない)

小数部分を得るには、少なくとも一方のオペランドを明示的に変換します:

double result = (double) a / b; // 3.5

エラー3: 小数の比較

浮動小数点数を等値比較に == で使わないでください。小さな許容誤差(epsilon)を用いた比較を行いましょう。

エラー4: float の精度喪失

大きな数値や高精度の値を float に保持しないでください。壊れたり、重要な桁を失ったりすることがあります。

コメント
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION