浮点程序验证:从基础算术到复杂运算
在浮点程序的开发中,确保程序的功能正确性至关重要。本文将深入探讨如何对浮点程序进行验证,包括使用功能契约、处理舍入误差、评估证明器性能,以及如何扩展方法以处理超越基本算术的运算。
1. 功能正确性与契约
为了进一步验证程序,需要添加功能契约来指定程序的预期行为。对于仅进行浮点计算的简单程序,将浮点结果与实数的精确计算结果进行比较是很有意义的。这样做不仅可以得到计算中舍入误差的上界,还能将实数计算中已知的属性应用到浮点计算中。
例如,在计算加权平均值时,实数的加权平均值会落在提供值的范围内,但由于舍入误差,浮点计算可能不满足这一条件。通过界定加权平均值计算中的舍入误差,可以更有效地收紧结果的边界。
2. 大实数库
为了编写描述舍入误差的规范,契约需要使用无限精度的运算。在即将发布的 Ada 中,新增了用于无限精度整数和有理数的库。其中,无限精度有理数库定义了一个名为 Big Real 的类型,它是两个无限精度整数的商。该库提供了有理数的常用运算,以及从浮点和整数类型的转换函数。在 SPARK 工具生成证明义务时, Big Real 类型的对象会被转换为数学实数,其操作也对应于实数操作,从而使 SPARK 能够受益于底层求解器的原生支持。
3. 指定浮点计算的舍入误差
契约通过对有理数进行计算的规范函数来表达。这些函数位于标记为 Ghost 的包中,这样在禁用断言编译代码时,它们将被消除,避免将 Big Reals 库链接到生产代码中。
超级会员免费看
订阅专栏 解锁全文

被折叠的 条评论
为什么被折叠?



