2011-09-27 56 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