double型

概要

小数を扱う浮動小数点型。

double 型は $64$ ビットの浮動小数点型(AtCoder環境の場合)。
符号用の $1$ ビット、値の桁数を表す指数部の $11$ ビット、値の並びを表す仮数部の $52$ ビットを使う。
仮数部では先頭の $1$ が省略されるため、精度は $53$ ビット分になる。

$0$ と、絶対値がおよそ $10^{-308}$ から $10^{308}$ までの数を表せる。
この範囲を逸脱することはまずないので、通常は気にしなくてよい。
むしろ、値が十進数でおよそ $15$ 桁の概数となるため、そちらによる影響を気にするべきである。

整数を double 型として扱いたい場合、2.0 のように書けば double 型の 2 となる。

宣言と初期化

宣言だけする場合

double a;

初期化もする場合

double a = 0.0;  // 固定値で初期化。0 とだけ書いても変換されるので問題ない
double b = a;    // 他の整数型や double 型の変数で初期化

可能な演算

代入 =

a=b; で、変数 a の中身を b に書き換える。
数学とは違い、左右を逆にして b=a; と書くと意味が変わるので注意。

int 型に double 型を代入すると、小数部分を捨てた値が代入される。(オーバーフローに注意)
double 型に int 型を代入すると、その整数と同じ値が代入される。

加算 +

a+b で、ab の和を計算する。
片方が整数型の場合も、結果は double 型になる。

減算 -

a-b で、ab の差を計算する。
片方が整数型の場合も、結果は double 型になる。

乗算 *

a*b で、ab の積を計算する。
片方が整数型の場合も、結果は double 型になる。

除算 /

a/b で、ab で割った値を計算する。
片方が整数型の場合も、小数部分まで計算し、結果は double 型になる。

各種複合代入演算子

double 型では、+=-=*=/= が使える。

よく使う処理

固定小数表示で出力する

double 型を cout で出力する場合、通常は有効数字 $6$ 桁で出力される。
値によっては 1.2e+06 のような表記になる。

固定小数表示にしたい場合は、以下のようにする。

cout << fixed << a << endl;

この場合は小数点以下 $6$ 桁を出力する。
もっと高い精度が求められる場合は、以下のように小数点以下の桁数を指定する。

cout << fixed << setprecision(10) << a << endl;

整数型の割り算を小数部分まで行う

整数型同士の割り算は、通常は整数部分だけを求める。
小数部分まで計算したい場合は、以下のようにする。

1.0*a/b

定数で割る場合は、以下のように書いてもよい。

a/10.0

整数への切り下げ、切り上げ、四捨五入

a 以下の最大の整数は floor(a) で求められる。
a 以上の最小の整数は ceil(a) で求められる。
最も近い整数は round(a) で求められる。

小数点以下を残した切り下げ、切り上げ、四捨五入

例えば、小数点以下 $1$ 桁を残す場合は、$10$ 倍して整数に丸めてから $10$ で割る。

小数点以下 $3$ 桁を残す場合なども同様に、$1000$ 倍してから丸め、$1000$ で割ればよい。

注意点

double 型の == 判定を信用してはいけない

double 型は概数で保持するため、末尾の数桁は不正確なことがある。
そのため、本来一致するはずの $2$ つの値が一致しないことがある。

例えば、以下のコードは No と出力される。

double a = 4.1;
double b = 3.1;
double c = 1.0;
if (a-b==c) cout << "Yes" << endl;
else cout << "No" << endl;

可能な限り、整数型で判定できる方法を考えた方が安全。

切り下げ時に誤差が発生することがある

本来ぴったり 3 のときに、内部の値が 2.9999999999 などになっていることがある。
この場合、floor によって 2 にされる可能性がある。

これを避けるために、非常に小さい値を足してから floor する手法がある。
ただし、a の値の大きさによって、事故も起こる。
足す値が小さすぎると影響がなかったり、大きすぎると 2.983.01 になったり、など。
適切な値を決めるのは難しいので注意。

関連アルゴリズム

int型

最も代表的な整数型。
double 型との演算では結果が double 型になり、double 型から代入すると小数部分が捨てられる。