这不是我的功课 - 我只是在练习。我似乎无法围绕这个断言概念。
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}.
答案 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甚至是整数,所以它有点暂时性。
如果x
和y
是浮点数或双精度数,那么在正常的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 < 0
,x == 0
和x > 0
,以确定x的哪些值满足后置条件。
答案 3 :(得分:0)
根据x
和y
的类型,答案可能会变得混乱。由于@PeteFordham指出二进制补码中的整数不对称,因此无法表示最大负整数的绝对值。如果不是整数x
和y
是float
或double
,那么您必须考虑在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的绝对值的函数(这可能是这个代码的用途,尽管你似乎已经省略了重要的部分问题陈述)。