【问题标题】:tSQLt Assert Failure Message Numeric PrecisiontSQLt 断言失败消息数值精度
【发布时间】:2013-06-21 10:01:43
【问题描述】:

如何提高 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] 失败:预期: 但为:

【问题讨论】:

    标签: tsqlt


    【解决方案1】:

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

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

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

    返回 -0.0001000000082740

    所以你也可以

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

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

    • 对变量使用精确的类型,例如NUMERIC (38, 19)。将示例中的每个 FLOAT 替换为 NUMERIC (38, 19) 似乎 会给出相同的结果,但是当您添加上面提到的 PRINT STR((@Actual - @Expected) * 1000000, 40, 20) 时,它现在会准确打印 -0.0001000000000000,说明PRINT语句也有不准确的地方

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

    更多信息:

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

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

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

    【讨论】:

    • @Hamish 如果此答案正确,请将其标记为正确,谢谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-16
    • 1970-01-01
    • 2019-07-11
    • 1970-01-01
    相关资源
    最近更新 更多