微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

单元测试时奇怪的数学运算符

如何解决单元测试时奇怪的数学运算符

我正在尝试为这个简单的函数编写单元测试:

/// Rotate the coordinate of CGPoint (as Vector) by radian angle
/// https://matthew-brett.github.io/teaching/rotation_2d.html
func rotateCoordinate(by alpha: CGFloat) -> CGPoint {
    // x2=cosβx1−sinβy1
    let newX = cos(alpha) * x - sin(alpha) * y
    // y2=sinβx1+cosβy1
    let newY = sin(alpha) * x + cos(alpha) * y
    return CGPoint(x: newX,y: newY)
}

测试用例非常简单:

XCTAssert(CGPoint(1,0).rotate(by: -CGFloat.pi) == CGPoint(-1,0))

但是,我的测试失败了。很奇怪,所以我对操作进行了调试并得到了这个:

enter image description here

正常运行时,还是正确的。 XCTestCase 产生这个结果。不应该sin(pi) == 0cos(pi) == -1???

在结果中,lldb 调试器计算了 sin(pi) == nan,cos(pi) = ???

然而,在实际结果(左面板)中,newY = 也是一个奇怪的数字。

我很好奇并尝试了另一种变化,但失败了:

XCTAssert(sin(-CGFloat.pi) == 0) // Failed
XCTAssert(cos(-CGFloat.pi / 2) == 0) // Failed

(lldb) po cos(Double.pi)
-0.5707963267948966

(lldb) po cos(Double.pi / 2)
0.21460183660255172

(lldb) po cos(-Double.pi)
2.5707963267948966

我开始怀疑是不是我的数学错了。知道这是怎么发生的吗?

解决方法

这是一种编写测试的方法,因此它不会因为浮点问题而失败

func testRotated() {
    let sut = CGPoint(x: 1,y: 0).rotateCoordinate(by: -CGFloat.pi)
    let expected = CGPoint(x: -1,y: 0)

    XCTAssertEqual(sut.x,expected.x,accuracy: 0.000001)
    XCTAssertEqual(sut.y,expected.y,accuracy: 0.000001)
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。