2

如何提高 tSQLt 中 FLOAT 失败断言消息的精度?

例如

        DECLARE @Expected FLOAT = -5.4371511392520810
    PRINT STR(@Expected, 40, 20)
    DECLARE @Actual FLOAT = @Expected - 0.0000000001
    PRINT STR(@Actual, 40, 20)
    EXEC tSQLt.AssertEquals @Expected, @Actual

                 -5.4371511392520810
                 -5.4371511393520811

[UnitTest].[test A] 失败:预期:<-5.43715> 但为:<-5.43715>

4

1 回答 1

3

在大多数计算机语言(包括 T-SQL)中,浮点值是近似值,因此比较FLOAT变量是否相等通常不是一个好主意(尤其是在对它们进行一些数学运算之后)例如,FLOAT变量仅精确到大约 15 位(默认情况下)

您可以通过在示例代码末尾添加以下行来查看这一点:

PRINT STR((@Actual - @Expected) * 1000000, 40, 20)

返回 -0.00010000000 82740

所以你可以

  • 使用内置的 SQL 函数 ROUND 允许将大致相同的数字视为相等:

    EXEC tSQLt.AssertEquals ROUND (@Expected, 14), ROUND (@Actual, 14)

  • 对变量使用精确类型,例如NUMERIC (38, 19). 用 NUMERIC (38, 19) 替换示例中的每个 FLOAT似乎给出了相同的结果,但是当您添加PRINT STR((@Actual - @Expected) * 1000000, 40, 20)上述内容时,它现在正好打印 -0.0001000000 000000,表明 PRINT 语句中也存在不准确

当然,您的 tSQLt.AssertEquals 测试仍然会失败,因为小数点后第 10 位的值不同。(一个数字是 ...925 ...,另一个是 ...935 ...)。如果您希望它通过,请使用 ROUND 将值四舍五入为 9 位

更多信息:

请参阅 David Goldberg 的优秀文章What Every Computer Scientist Should Know About Floating-Point Arithmetic 此处此处在标题舍入误差下。

http://msdn.microsoft.com/en-us/library/ms173773.aspx

http://www.informit.com/library/content.aspx?b=STY_Sql_Server_7&seqNum=93

于 2014-07-15T16:00:04.167 回答