外观
csapp/bits.c
配套源码,运行方法见同目录 README。返回实验总览。
c
/* Original exercises: defined C11 operations, not restricted Data Lab answers. */
#include <assert.h>
#include <inttypes.h>
#include <limits.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
static unsigned population(uint32_t value) {
unsigned count = 0;
while (value) {
value &= value - UINT32_C(1);
++count;
}
return count;
}
static uint32_t rotate_left(uint32_t value, unsigned amount) {
amount %= 32;
if (amount == 0) return value; /* A shift by 32 would be undefined. */
return (value << amount) | (value >> (32 - amount));
}
static bool add_i32(int32_t a, int32_t b, int32_t *out) {
int64_t wide = (int64_t)a + b;
if (wide < INT32_MIN || wide > INT32_MAX) return false;
*out = (int32_t)wide;
return true;
}
int main(void) {
assert(CHAR_BIT == 8);
assert(population(0) == 0);
assert(population(UINT32_MAX) == 32);
assert(population(UINT32_C(0x80000001)) == 2);
assert(rotate_left(UINT32_C(0x80000001), 1) == 3);
assert(rotate_left(UINT32_C(0x80000001), 0) == UINT32_C(0x80000001));
assert(rotate_left(UINT32_C(0x80000001), 32) == UINT32_C(0x80000001));
int32_t result = 99;
assert(!add_i32(INT32_MAX, 1, &result) && result == 99);
assert(!add_i32(INT32_MIN, -1, &result) && result == 99);
assert(add_i32(INT32_MIN, INT32_MAX, &result) && result == -1);
assert(add_i32(15, -7, &result) && result == 8);
uint32_t word = UINT32_C(0x12345678);
unsigned char bytes[sizeof word];
memcpy(bytes, &word, sizeof bytes);
printf("memory bytes: %02x %02x %02x %02x\n", bytes[0], bytes[1], bytes[2], bytes[3]);
printf("wrap: %" PRIu32 "\n", UINT32_MAX + UINT32_C(1));
puts("bits: boundary checks passed");
return 0;
}