0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【C#】0.1を1000回足すと100.0にならない件

Posted at

どういうこと?

下記のソースコードを実行するとなぜか結果は100になりません。

0.1を1000回足す(double)
double sumData = 0;

for (int i = 1; i <= 1000; i++)
{
    //0.1を1000回足す!
    sumData += 0.1;
}

Console.WriteLine(sumData);
//出力:99.9999999999986

↓結果↓
image.png

なんで?

参考にしたサイトがとても分かりやすく解説されているのでそのまま引用します。

SingleやDoubleのような浮動小数点数型は、値を2進数で格納しています。しかし、ほとんどの10進数の小数は2進数で表現することができません。そのためこのような値はSingleやDouble型では近似値でしか表現することができず、その誤差が上記のような非常識的な計算結果として現れます。

引用:小数(浮動小数点数型)の計算が思った結果にならない理由と解決法

...(´ε` )ふぅん(今まで実装してきたソフト大丈夫かな...)

どうすんの?

Decimal型を使います。
上記で引用したサイトがこれまた分かりやすくされているのでそのまま引用します。

10進数の小数を2進数に変換するときの丸め誤差をなくすには、SingleやDouble型の代わりにDecimal型を使用します。Decimal型は10進数の小数でも正確に表現することができます。

引用:小数(浮動小数点数型)の計算が思った結果にならない理由と解決法

ということでソースコードのsumData変数をDecimal型にして再度試してみました。

0.1を1000回足す(decimal)
decimal sumData = 0;

for (int i = 1; i <= 1000; i++)
{
    //0.1を1000回足す!
    sumData += (decimal)0.1;
}

Console.WriteLine(sumData);
//出力:100.0

↓結果↓
image.png

どっち使えばいいの?

  • 基本的にはdouble型を使います。
  • お金などが関わっている場合(勘定ソフトや会計処理)はdecimal型を使います。

理由

decimal型の処理は他の型に比べて計算がくっそ遅いです。ただし、速度よりも精度を求められる場面ではdecimal型を採用しないと正しくない計算結果が算出される可能性があります。ちなみにdouble型の有効桁数は15~17桁です。

それぞれの型で0.1を1億回足すのにかかる時間を検証しました。
結果は下記になりました。

single double decimal
2138[ms] 2105[ms] 14784[ms]
検証したソースコード
decimal sumData = 0;

var sum = (decimal)0.1;

var sw = Stopwatch.StartNew();

for (int i = 1; i <= 1000000000; i++)
{
    //0.1を1000000000回足す!
    sumData += sum;
}

sw.Stop();

Console.WriteLine($"{sw.ElapsedMilliseconds}[ms]");

余談

プログラミング学習1ヶ月目の時に電卓を作りましたが、あの時のソースコードを見てみたらdouble型を使ってました。(゚A゚;)ゴクリ...(世の中に出るソフトじゃなくて良かったぁ)

ここまで読んで頂いてありがとうございました!

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?