2011-09-27 57 views
6

我很難過。這是我的測試用例。聲明失敗時,它不應該在Smalltalk單元testcase

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

斷言不應該失敗。在計算每個元素的平方是正確的。所以我做了「步入測試」,顯示方法squareOfAllElements和#(1.44 9 26.01 49)的結果都是相同的,但assert評估爲false。爲什麼?我在這裏做錯了什麼?任何幫助表示讚賞。

回答

0

然而,比較平等消息,#=,被髮送到由#squareOfAllElements想必返回的集合。

你可以重寫你的測試語句:

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

這將測試同前一個,但會運行一個#assert:每個元素。

其他選項可以實現#hasEqualElements的變體:根據Float >>#equal:而不是#=。

0

正如在其他答案中所說,Float是不精確的。另外請記住,Visualworks Float默認爲單精度(約7位小數),如果你使用字母d來填充浮點數,就像5.1d一樣,你將得到雙精度(大約15位小數),不精確但仍不精確。

另一個混亂的原因是兩個不同的Float可以在Visualworks中使用相同的近似小數表示形式進行打印。

5.1 squared printString 
-> '26.01' 

5.1 squared = 26.01 
-> false 

注意,最近佳樂或菲羅打印剛夠小數來區分不同的浮動(和重新解釋不變)

5.1 squared 
->26.009999999999998 

或者,你可以用所謂的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