c ++前提条件/断言

时间:2013-02-28 04:21:41

标签: c++ assertions preconditions

这不是我的功课 - 我只是在练习。我似乎无法围绕这个断言概念。

1) Determine the pre-condition for x that guarantees the post-condition about y
{ _______ }
if (x > 0)
    y = x;
else
    y = -x;

{ y >= 0 && |y| == |x| }
2) This code is the same as has been seen before, but the post-condition is different.                    
Describe why this post-condition is better for verifying the code than just { y >= 0}.

5 个答案:

答案 0 :(得分:2)

如果你这样做是为了学习编程,你可以做一些编程来帮助你确认答案:

#include <iostream>

int abs(int x) { return x >= 0 ? x : -x; }

int main()
{
    for (int i = -128; i <= 127; ++i)
    {
        char x = i;

        char y;

        if (x > 0)
            y = x;
        else
            y = -x;

        if (!(y >= 0 && abs(y) == abs(x)))
            std::cout << "failed for " << i << " (y " << (int)y << ")\n";
    }
}

运行此功能,您会看到x -128(y为-128)是否失败。这是由于2的补码表示法的不对称性:-128可以用8位字符表示,但128不能(只有127)。

因此,对于1,假设2的补码整数,前提是x不是位宽中可表示的最低值。当然,问题中没有任何内容表示x和y甚至是整数,所以它有点暂时性。

如果xy是浮点数或双精度数,那么在正常的IEEE表示中,有一个符号位可以在不影响尾数或指数的情况下切换,允许“干净”改变符号。也就是说,还存在“非数字”(NaN)和(正和负)无限哨兵值的极端情况,通过实验和/或通过研究表示和行为规范进行检查是明智的。

  

描述为什么[{y&gt; = 0&amp;&amp; | Y | == | x |验证代码比{y&gt; = 0}更好。

一个模糊的问题,因为我们对代码试图实现的内容并不确定,而我们对此的推理来自于前一个后置条件优于后者的断言。尽管如此,他们仍在寻找一个答案:前者还确保​​y的绝对量级能够幸免于代码对x所做的任何符号更改。

在实践中,对于我们的2的补码整数,其幅度在之后总是匹配 - 这是后置状态的标志部分,标志着角落情况。但是,对于对预期的内容进行更深入的了解仍然令人放心。

答案 1 :(得分:1)

我猜是因为通常整数类型可以表示来自(-N)&gt; 0> (N-1)。也就是说,如果你的int是带符号的32位整数,它可以保存值-2147483648但不能保存值2147483648.

{x!= INT_MIN}

答案 2 :(得分:0)

从帖子条件向后工作。只有一个分支声明。由于if语句测试x&gt; 0然后只查看3个案例:x < 0x == 0x > 0,以确定x的哪些值满足后置条件。

答案 3 :(得分:0)

根据xy的类型,答案可能会变得混乱。由于@PeteFordham指出二进制补码中的整数不对称,因此无法表示最大负整数的绝对值。如果不是整数xyfloatdouble,那么您必须考虑在IEEE格式中,零可以同时具有正号和负号。

#include <iostream>
int main() {
    double x = 0;
    double y = -x;
    std::cout << "x=" << x << " y=" << y << std::endl;
}

输出

  

x = 0 y = -0

答案 4 :(得分:0)

如果x>由于if (x > 0) y = x,总是满足0,y> = 0。如果x == 0,由于if ( x > 0) ... else y = -x,总是满足y&gt; = 0。如果x < 0,y = -x因此,除非-x <0,否则满足y> = 0。所以前提条件是{x> = 0 || -x&gt; = 0}。 (x的唯一值不是真的是最大的否定值,它会溢出。)

{y&gt; = 0&amp;&amp; | Y | == | x | }比{y> = 0}更好,因为后者适用于所有类型的函数,而不仅仅是找到x的绝对值的函数(这可能是这个代码的用途,尽管你似乎已经省略了重要的部分问题陈述)。