2011-09-27 14 views
6

私は困惑しています。ここに私のテストケースがあります。アサートは失敗するべきではありません。スモールトークユニットテストケース

theTestArray := #(1.2 3 5.1 7). 
self assert: theTestArray squareOfAllElements = #(1.44 9 26.01 49). 

アサートは失敗してはなりません。各要素の二乗の計算には正しいです。だから、私は "test into step"を実行して、squareOfAllElementsと#(1.44 9 26.01 49)メソッドの結果が同じであることを示していますが、アサーションはfalseと評価します。どうして?私はここで間違って何をしていますか?どんな助けもありがとうございます。

答えて

8

ここで浮動小数点数を扱っています。浮動小数点数は定義によって不正確です。#=を使用して浮動小数点数を比較しないでください。詳細について

は例によってファロの浮動小数点数にドラフト章のセクション1.1をご確認ください:http://stephane.ducasse.free.fr/Web/Draft/Float.pdf

0

しかし、比較平等メッセージ、#1 =は、おそらく#squareOfAllElementsによって返されるコレクションに送信されます。

あなたは、あなたのテスト文を書き換えることができるように:要素ごとに:前回と同じテストをしますが、1つの#assert指令を実行します

theTestArray := #(1.2 3 5.1 7). 
theSquaredArray := theTestArray collect: [:each | each squared]. 
theTestArray with: theSquaredArray do: [:a :b | self assert: (a equals: b) ]. 

その他のオプションは#hasEqualElementsのバリエーションを実装することです:Float >>#equalの代わりに#=の代わりに使用します。

0

他の回答で述べたように、フロートは不正確です。また、浮動小数点数を文字dで置き換えると、倍精度(約15桁の小数点以下)を得ることができますが、不正確ではありませんが、不正確なままであることに注意してください。

もう1つの混乱の原因は、2つの異なるFloatがVisualworksで同じ10進表現を使用して印刷できることです。

5.1 squared printString 
-> '26.01' 

ちょうど十分な小数最近Squeakのか、ファロのプリントが

5.1 squared 
->26.009999999999998 

また別のフロートを区別(と変わらず、それらを再解釈)する

5.1 squared = 26.01 
-> false 

注意、あなたは、いわゆるを使用することができます正確な操作を実行するためのFixedPoint(VisualWorksまたは他の味のScaledDecimals):

theTestArray := #(1.2s 3 5.1s 7). 
self assert: theTestArray squareOfAllElements = #(1.44s 9 26.01s 49). 

FixedPoint(ScaledDecimals)は、小数点の後に小数点以下の小数点以下を表示しますが、内部ではより多くの(無限に)保持することができます。

5.1s1 squared printString 
-> '26.0s1' 

しかし

5.1s1 squared = 26.01s2 
-> true 
関連する問題