2017-01-26 13 views
-2

範囲とステップを持つDoublesのコレクションを作成しようとしています。私はArray.iterateメソッドを使用すると私はそのようなのような奇妙な浮動小数点エラーを取得:小さな一歩の小さな範囲は、このような不正確さを引き起こすことを奇妙に思えるスカラ反復と範囲の精度エラー

scala> Array.iterate[Double](0.0, 10)(0.1+) 
res0: Array[Double] = Array(0.0, 0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6, 0.7, 0.7999999999999999, 0.8999999999999999) 

。私はこれを行うことができる他の方法があることを認識しています(例えばArray.iterate[Int](0, 10)(1+).map(i => i.toDouble/10.0))が、組み込みの組み込みメソッドがあまりにもひどく機能することにはうんざりしています。これには理由があるのですか、それとも私はそれを間違ったやり方でやっていますか?

+0

? REPLで '0.1 + 0.1 + 0.1'を実行しようとすると' 0.30000000000000004'となるでしょう – Tim

答えて

1

はBigDecimalのを使用してみてください:この期待できない行動がどのように

scala> val r = BigDecimal(0) to BigDecimal(1) by BigDecimal(0.1) 

scala> println(r) 
NumericRange(0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0) 
+0

このような範囲で 'BigDecimal'を使うことができるのは間違いありませんが、 'インスタンスは通常の小数点とは違って印刷されていますが、エラーはまだあります)。 –

+0

興味深い、thanks @ evan058。好奇心の念から、実際には "敷物の下でそれを掃除"するのではなく、実際にエラーに対処する方法はありますか? –

+0

可能であれば 'Rational' numbersクラスを使用します。そうでない場合、' BigDecimal'のようなしきい値が実行されています。浮動小数点数の制限を理解することは、絶対に不可欠です。 –

関連する問題