質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

Q&A

解決済

1回答

2673閲覧

Swiftの配列内での計算結果をprintで正常に出力できない

umerin

総合スコア13

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

0グッド

2クリップ

投稿2016/08/05 22:03

###前提・実現したいこと
Swiftを勉強しようと思っていて、よきせぬ出力がでたので、もやもやを解決したい。

###発生している問題

配列の中で小数点の計算(例:1.2 / 6.0)をして、その配列をprintで出力すると、想定している計算結果(0.2)が出てこない。

###該当のソースコード

swift

1var a = 1.2; 2var b = [ i, 1.2 / 6.0, i * 2.2] //[1.2, 0.2, 2.64] 3 4print(b) //[1.2, 0.19999999999999998, 2.6400000000000001]\n

###試したこと

配列内ではなく、printの中で計算してみたら予想通りの値が出ました。

swift

1print(1.2 / 6.0) //0.2\n

###補足情報(言語/FW/ツール等のバージョンなど)
Xcode バージョン 7.3.1 (7D1014)のPraygroundで実行しました。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

これは、浮動小数点の丸め誤差によるものです。
浮動小数点(double,float)を扱うコンピュータ言語共通の仕様で、
Swift言語特有の問題ではありません。

コンピュータは、2進数(2のn乗の組み合わせ)で数値を表現する機械なので、
実は10進数の少数点を正確に表現できないのです。

例えば、1.2という数値は
2の0乗=1
(2の-1乗=0.5は加算しない)
(2の-2乗=0.25は加算しない)
2の-3乗=0.125
2の-4乗=0.0675

といった形で2のマイナスn乗を順次加えて行って、できるだけ1.2に近い値で表現しているだけなのです。
なので、10進数の1.2という値を正確に表現できてないのです。
詳しくは、
http://www.cc.kyoto-su.ac.jp/~yamada/programming/float.html
とかを参照してください。

1.2/6.0は、実は内部では
0.19999999999999998
という0.2に近い値で格納されているのですが、
それを表示する際、最終桁を四捨五入して表示する機能が入っていたりするので
print(1.2/6.0)
は0.2と出力されるのだと思います。
print(b)で配列を出力した時は、内部の要素を出力する時に、そういう四捨五入機能が入ってなくて、そのままの値が出ているのだと思います。

もっとわかりやすいというか、危険だということを認識してほしい例があります。

swift

1let c = 1.2/6.0 2if c == 0.2 { 3 print("cは0.2です") 4} else { 5 print("cは0.2ではありません") 6}

をplaygroundで実行してみてください。
「cは0.2ではありません」と出力されると思います。

さらに

swift

1let d = 0.1+0.2 2if d == 0.3 { 3 print("dは0.3です") 4} else { 5 print("dは0.3ではありません") 6}

は「dは0.3ではありません」と出力されると思います。

このように、コンピュータは小学生でもできる0.1+0.2の計算がちゃんとできないのです。

プログラマーは、このことをちゃんと意識してプログラミングする必要があります。
少数点の計算結果がある値と等しいか、==で比較するのは厳禁と考えるべきで、

=や<=で閾値を超えたか否かで比較すべきということです。

投稿2016/08/05 23:09

編集2016/08/05 23:38
TakeOne

総合スコア6299

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

umerin

2016/08/06 01:44

丁寧な回答ありがとうございます。配列をprintで出力するとそのまま出力してしまうのではないかということで、納得しました。本当に、小数点の計算は怖いと思いました。ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問