Reputation: 31
This is not my homework -- I'm just practicing. I can't seem to wrap my mind around this assertion concept.
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}.
Upvotes: 3
Views: 1808
Reputation: 16406
If x > 0, y >= 0 is always satisfied due to if (x > 0) y = x
. If x == 0, y >= 0 is always satisfied due to if ( x > 0) ... else y = -x
. If x < 0, y = -x so y >= 0 is satisfied unless -x < 0. So the precondition is { x >= 0 || -x >= 0 }. (The only value of x for which that isn't true is the max neg value, which overflows.)
{ y >= 0 && |y| == |x| } is better than { y >= 0 } because the latter is true for all sorts of functions, not just one that finds the absolute value of x (which is presumably what this code is for, although you seem to have elided vital parts of the problem statement).
Upvotes: 0
Reputation: 106096
If you're doing this to learn about programming, you can do a bit of programming to help you confirm the answer:
#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";
}
}
Running this you'll see if fails for x
-128 (where y
is -128). This is due to the asymmetry in 2's complement notation: -128 can be represented in an 8-bit char, but 128 can not (only 127).
So for 1, and assuming 2's complement integers, the precondition is that x
is not the lowest representable value in your bit width. Of course, there's nothing in the question that says x and y are even ints, so it's all a bit tentative.
If x
and y
were floats or doubles say, then in the normal IEEE representations there's a sign bit that can be toggled without affecting the mantissa or exponent, allowing a "clean" change of sign. That said, there are also corner cases with "not a number" (NaN) and (positive and minus) infinity sentinel values, which it would be wise to check either experimentally and/or by studying the representations and behavioural specifications....
Describe why [{ y >= 0 && |y| == |x| }] is better for verifying the code than just { y >= 0}.
A vague question, as we've no certainty about what the code's trying to achieve, and our reasoning about that comes circularly from the assertion that the former post-condition is better than the latter. Still, they're fishing for an answer like: the former also ensures the absolute magnitude of y
survives whatever the sign change made by the code does to x
.
In practice for our 2's complement integers the magnitude did always match afterwards - it was the sign part of the post-condition that flagged the corner case. But, it's still reassuring to have that extra insight into what's expected.
Upvotes: 2
Reputation: 11582
The answer to this can get messy depending on the type for x
and y
. As @PeteFordham pointed out integers in two's complement aren't symmetric, the absolute value of the maximum negative integer cannot be represented. If instead of integers x
and y
are float
or double
then you have to consider that in IEEE format zero can have both a positive and negative sign.
#include <iostream>
int main() {
double x = 0;
double y = -x;
std::cout << "x=" << x << " y=" << y << std::endl;
}
the output is
x = 0 y = -0
Upvotes: 1
Reputation: 2343
I'd guess because typically an integer type can represent from (-N) > 0 > (N-1). That is to say if your int is a signed 32 bit integer it could hold the value -2147483648 but not the value 2147483648.
{ x != INT_MIN }
Upvotes: 2
Reputation: 13189
Work backwards from the post condition. There is only one branch statement. Since the if statement tests x > 0 then just look at the 3 cases: x < 0
, x == 0
, and x > 0
to determine which values of x satisfy the post-condition.
Upvotes: 0