#include /* Two's Complement Examples for CS250 * Please read this, and I'll write a multiple choice question about it */ /* Remember: When a signed integer reaches its limit, it goes to the bottom * of the range. So (unsigned char)127 + 1 = -128. * 0x7f + 1 = 0x80 * 0x80 is -128 */ int main(){ /* %hhd is a signed 8-bit integer */ /* Note that the integers can go one farther in the negative direction * This is -128 */ printf("%hhd\n", 0x80); /* Numbers count up again from the bottom. * This is -1, right before we get back to 0 */ printf("%hhd\n", 0xff); /* The negative can value can be computed like this: * 1. Flip every bit (using the C bitwise not here) * 2. Add 1 to the result */ int x = -34; x = ~x; x += 1; printf("x = %d\n", x); /* If we want the negative sign back: * 1. Flip all bits * 2. Add 1 to the result */ x = ~x; x += 1; printf("x = %d\n", x); /* Macro to comput absolute value. * 1. Determine if the number is negative or not by checking the sign bit. * The sign bit is on the far left, but width varies based on type * For an int, it is 32 bits over, but for a long int, it is 64 * We can use sizeof to calculate the correct shift * 2. Based on the test above, either flip all bits and add one, or don't */ #define ABS(N) (((N >> (sizeof(N) * 8 - 1)))? ~N+1 : N) /* Efficiency note: Instead of calculating the shift every time, we could * keep a separate macro for each integer width. */ #define ABS_8(N) ((N >> 7)? ~N+1 : N ) #define ABS_16(N) ((N >> 15)? ~N+1 : N) /* ... and so on for all the other sizes. Probably with some kind of #ifdef * that I don't feel inclined to figure out right now, we could even make a * way to pick the right one automatically */ x = -30; long int y = -27; char z = -6; printf("ABS(x) = %d\n", ABS(x)); printf("ABS(y) = %ld\n", ABS(y)); printf("ABS(z) = %hhd\n", ABS(z)); printf("ABS(55) = %d\n", ABS(55)); printf("ABS(-55) = %d\n", ABS(-55)); return 0; }