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

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

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

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

Swift

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

Q&A

解決済

2回答

1214閲覧

浮動小数点で生じる誤差を修正したい。

testyoutatsu

総合スコア29

Xcode

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

Swift

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

0グッド

0クリップ

投稿2018/08/06 15:31

編集2018/08/07 03:07

前提・実現したいこと

Double型の小数を引き算し、小数点以下4桁を切り捨てしたい。

小数点以下3桁同士の引き算をしたいのですが、計算結果に誤差が生じてしまいます。
以下のようなコードで小数点以下4桁を切り捨てようとしましたが、3.8999999999999999のような値を返してしまいます。
浮動小数点で誤差が生じてしまうのを修正したいです。

質問用にコードを書き換えていたので、そのままのコードを追記しました。
print(Double(range)/1000) では誤差は生じていませんが、配列pipsに格納すると誤差が生じます。

ソースコード

Swift

1 func roundingOffe() { 2 3 for i in 0...9 { 4 var range = floor(fabs(Double(dictionary[i][1])!) - Double(dictionary[i][4])!) * 100000 )) 5 array[i] = range) / 1000 6 } 7 8 print(array) //[12.199, 3.8999999999999999, 2.899, 8.6989999999999998, 42.399999999999999, 15.298999999999999, 0.69999999999999996, 1.8, 5.5999999999999996, 10.099] 9 10 } 11 12 13 14//追記 15 func range() { 16 17 for i in 0...9 { 18 19 var range = Int(floor(fabs(Double(newDictionary[2*(2*i+1)][1])! - Double(newDictionary[2*(2*i+4)][4])!) * 100000 )) 20 21 print(Double(range)/1000) 22 //=>12.199 3.9 2.899 8.699 42.4 15.299 0.7 1.8 5.6 10.099 23 24 pips[i] = Double(range) / 1000 25 26 } 27 28 print(pips) 29 //=>[12.199, 3.8999999999999999, 2.899, 8.6989999999999998, 42.399999999999999, 15.298999999999999, 0.69999999999999996, 1.8, 5.5999999999999996, 10.099] 30 31 }

試したこと

floor()、round()両方試しました。Int型に直してから/1000してDouble型に戻しても誤差が生じてしまいます。

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

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

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

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

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

fuzzball

2018/08/07 00:15

エラーの出ないコードを書いてください。また、そのままで検証できるコードを書いていただけるとありがたいです。
guest

回答2

0

ベストアンサー

表示の問題なので気にしなくていいと思います。(第三位くらいなら)
表示を気にしているのであれば書式を使うなどして下さい。

swift

1let value = [3.9, 2.9, 42.4] 2 3print(value) 4//=> [3.8999999999999999, 2.8999999999999999, 42.399999999999999] 5 6print(value[0], value[1], value[2]) 7//=> 3.9 2.9 42.4 8 9print(String(format: "%.3f %.3f %.3f", value[0], value[1], value[2])) 10//=> 3.900 2.900 42.400 11

投稿2018/08/07 00:56

fuzzball

総合スコア16731

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

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

testyoutatsu

2018/08/07 03:13

今回は表示を気にしているので最後に書式を変更してみようと思います。ありがとうございました。
guest

0

10進数の0.1は浮動小数点(2進数)では表現できません

浮動小数点数で誤差が生じる、のではなく、浮動小数点数を10進で表現させようとするのが無理、ということですね

どうしても、質問のようなことがやりたいのなら、*1000して整数で保存し、表示するときは/1000 と、小数点以下は1000の剰余で表示するようにしましょう

投稿2018/08/06 15:53

y_waiwai

総合スコア87719

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

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

testyoutatsu

2018/08/07 03:09

回答ありがとうございます。なるほど、原因は理解できました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問