labs only

This commit is contained in:
18218461270@163.com 2025-08-19 12:09:36 +08:00
parent 8ae7b4b9e9
commit e6cc51df09
28 changed files with 1 additions and 488 deletions

View File

@ -1,3 +1,3 @@
# CSAPP-sol # CSAPP-sol
CSAPP中homework和lab的部分题目的参考答案 CSAPP labs

View File

@ -1,13 +0,0 @@
#
# Makefile that builds btest and other helper programs for the CS:APP data lab
#
CC = gcc
CFLAGS = -O2 -Wall -m32
LIBS = -lm
all: test
test: main.c homework.c test.c test.h xoroshiro128plusplus.c
$(CC) $(CFLAGS) $(LIBS) -o test main.c homework.c test.c xoroshiro128plusplus.c
clean:
rm -f test

View File

@ -1,2 +0,0 @@
第二章作业 65、66、75、80、95 和 97 的测试框架。你需要编辑 homework.c 中的六个函数完成作业,然后输入命令 make 编译程序,输入命令 ./test 查看结果。
homework_sample.c 中有参考实现。

View File

@ -1,104 +0,0 @@
#include "test.h"
/* Return 1 when x contains an odd number of 1s; 0 otherwise.
Assume w=32 */
int odd_ones(unsigned x) {
x ^= x >> 16;
x ^= x >> 8;
x ^= x >> 4;
x ^= x >> 2;
x ^= x >> 1;
return x & 1;
}
/*
* Generate mask indicating leftmost 1 in x. Assume w=32.
* For example, 0xFF00 -> 0x8000, and 0x6600 --> 0x4000.
* If x = 0, then return 0.
*/
int leftmost_one(unsigned x) {
unsigned t = x;
t >>= 1;
t |= t >> 1;
t |= t >> 2;
t |= t >> 4;
t |= t >> 8;
t |= t >> 16;
return (t + 1) & x;
}
unsigned unsigned_high_prod(unsigned x, unsigned y) {
int w = sizeof(int) << 3;
return signed_high_prod(x, y) + (((int) y >> (w - 1)) & x) + (((int) x >> (w - 1)) & y);
}
int threefourths(int x) {
int p = x >> 2, q = x & 3;
return p + (p << 1) + q - (!!q & (~x >> 31));
}
/* computs 0.5*f. If f is NaN, then return f. */
float_bits float_half(float_bits uf) {
float_bits s = uf & 0x80000000, f = uf & 0x007FFFFF, e = (uf >> 23) & 0xFF;
if (e == 0xFF) {
return uf;
}
if (e > 1) {
e--;
} else {
if (e == 1) {
f |= 1 << 23;
e = 0;
}
int t = f;
f >>= 1;
if (t & f & 1) {
f++;
}
}
return s | (e << 23) | f;
}
/* Compute (float) i */
float_bits float_i2f(int i) {
if (i == -0x7FFFFFFF - 1) {
return 0xCF000000;
}
if (i == 0) {
return 0;
}
float_bits s = 0, f, e;
if (i < 0) {
i = -i;
s = 0x80000000;
}
int hb = 30;
while (!(i >> hb)) {
hb--;
}
i ^= 1 << hb;
e = hb + 127;
int dif = hb - 23;
if (dif > 0) {
f = i >> dif;
if ((i & ((1 << dif) - 1)) + (f & 1) > (1 << (dif - 1))) {
f++;
if (f & 0x00800000) {
f = 0;
e++;
}
}
} else {
f = i << -dif;
}
return s | (e << 23) | f;
}

View File

@ -1,104 +0,0 @@
#include "test.h"
/* Return 1 when x contains an odd number of 1s; 0 otherwise.
Assume w=32 */
int odd_ones(unsigned x) {
x ^= x >> 16;
x ^= x >> 8;
x ^= x >> 4;
x ^= x >> 2;
x ^= x >> 1;
return x & 1;
}
/*
* Generate mask indicating leftmost 1 in x. Assume w=32.
* For example, 0xFF00 -> 0x8000, and 0x6600 --> 0x4000.
* If x = 0, then return 0.
*/
int leftmost_one(unsigned x) {
unsigned t = x;
t >>= 1;
t |= t >> 1;
t |= t >> 2;
t |= t >> 4;
t |= t >> 8;
t |= t >> 16;
return (t + 1) & x;
}
unsigned unsigned_high_prod(unsigned x, unsigned y) {
int w = sizeof(int) << 3;
return signed_high_prod(x, y) + (((int) y >> (w - 1)) & x) + (((int) x >> (w - 1)) & y);
}
int threefourths(int x) {
int p = x >> 2, q = x & 3;
return p + (p << 1) + q - (!!q & (~x >> 31));
}
/* computs 0.5*f. If f is NaN, then return f. */
float_bits float_half(float_bits uf) {
float_bits s = uf & 0x80000000, f = uf & 0x007FFFFF, e = (uf >> 23) & 0xFF;
if (e == 0xFF) {
return uf;
}
if (e > 1) {
e--;
} else {
if (e == 1) {
f |= 1 << 23;
e = 0;
}
int t = f;
f >>= 1;
if (t & f & 1) {
f++;
}
}
return s | (e << 23) | f;
}
/* Compute (float) i */
float_bits float_i2f(int i) {
if (i == 0x7FFFFFFF - 1) {
return 0xCF000000;
}
if (i == 0) {
return 0;
}
float_bits s = 0, f, e;
if (i < 0) {
i = -i;
s = 0x80000000;
}
int hb = 30;
while (!(i >> hb)) {
hb--;
}
i ^= 1 << hb;
e = hb + 127;
int dif = hb - 23;
if (dif > 0) {
f = i >> dif;
if ((i & ((1 << dif) - 1)) + (f & 1) > (1 << (dif - 1))) {
f++;
if (f & 0x00800000) {
f = 0;
e++;
}
}
} else {
f = i << -dif;
}
return s | (e << 23) | f;
}

View File

@ -1,40 +0,0 @@
#include <stdio.h>
#include "test.h"
int main() {
if (test_65() == FAILED) {
fprintf(stderr, "HOMEWORK 65 TEST FAILED\n");
} else {
fprintf(stderr, "HOMEWORK 65 TEST PASSED\n");
}
if (test_66() == FAILED) {
fprintf(stderr, "HOMEWORK 66 TEST FAILED\n");
} else {
fprintf(stderr, "HOMEWORK 66 TEST PASSED\n");
}
if (test_75(1e9) == FAILED) {
fprintf(stderr, "HOMEWORK 75 TEST FAILED\n");
} else {
fprintf(stderr, "HOMEWORK 75 TEST PASSED\n");
}
if (test_80(1e9) == FAILED) {
fprintf(stderr, "HOMEWORK 80 TEST FAILED\n");
} else {
fprintf(stderr, "HOMEWORK 80 TEST PASSED\n");
}
if (test_95() == FAILED) {
fprintf(stderr, "HOMEWORK 95 TEST FAILED\n");
} else {
fprintf(stderr, "HOMEWORK 95 TEST PASSED\n");
}
if (test_97() == FAILED) {
fprintf(stderr, "HOMEWORK 97 TEST FAILED\n");
} else {
fprintf(stderr, "HOMEWORK 97 TEST PASSED\n");
}
}

View File

@ -1,101 +0,0 @@
#include <math.h>
#include <stdio.h>
#include <assert.h>
#include <limits.h>
#include <stdint.h>
#include "test.h"
uint64_t next();
void jump();
void long_jump();
int test_65() {
for (unsigned x = 0; ; x++) {
if (odd_ones(x) != __builtin_parity(x)) {
fprintf(stderr, "x = 0x%X\n", x);
return FAILED;
}
if (x == UINT_MAX) {
return PASSED;
}
}
}
int test_66() {
for (unsigned x = 0; ; x++) {
if ((x == 0 && leftmost_one(x) != 0) || (x != 0 && leftmost_one(x) != (1 << (31 - __builtin_clz(x))))) {
fprintf(stderr, "x = 0x%X\n", x);
return FAILED;
}
if (x == UINT_MAX) {
return PASSED;
}
}
}
int test_75(int test_cases) {
for (int i = 0; i < test_cases; i++) {
unsigned x = next(), y = next();
if ((uint64_t) x * y != ((uint64_t) unsigned_high_prod(x, y) << 32) + x * y) {
fprintf(stderr, "x = 0x%X, y = 0x%X\n", x, y);
return FAILED;
}
}
return PASSED;
}
int signed_high_prod(int x, int y) {
int64_t p = (int64_t) x * y;
return p >> (sizeof(int) << 3);
}
int test_80(int test_cases) {
for (int i = 0; i < test_cases; i++) {
int x = next();
if (threefourths(x) != (int64_t) x * 3 / 4) {
fprintf(stderr, "x = 0x%X\n", x);
return FAILED;
}
}
return PASSED;
}
float_bits f2b(float x) {
return *(float_bits*) &x;
}
float b2f(float_bits x) {
return *(float*) &x;
}
int test_95() {
for (float_bits x = 0; ; x++) {
float y = b2f(x) / 2, z = b2f(float_half(x));
if (y != z && !(isnan(y) && isnan(z))) {
fprintf(stderr, "%X %X\n", f2b(b2f(x) / 2), float_half(x));
fprintf(stderr, "f = 0x%X\n", x);
return FAILED;
}
if (x == UINT_MAX) {
return PASSED;
}
}
}
int test_97() {
for (int x = INT_MIN; ; x++) {
if (f2b((float) x) != float_i2f(x)) {
fprintf(stderr, "i = 0x%X\n", x);
return FAILED;
}
if (x == INT_MAX) {
return PASSED;
}
}
}

View File

@ -1,26 +0,0 @@
#ifndef TEST_H
#define TEST_H
#define PASSED 0
#define FAILED 1
/* Access bit-level representation of floating-point number */
typedef unsigned float_bits;
int signed_high_prod(int, int);
int odd_ones(unsigned);
int leftmost_one(unsigned);
unsigned unsigned_high_prod(unsigned, unsigned);
int threefourths(int);
float_bits float_half(float_bits);
float_bits float_i2f(int);
int test_65();
int test_66();
int test_75(int);
int test_80(int);
int test_95();
int test_97();
#endif

View File

@ -1,97 +0,0 @@
/* Written in 2019 by David Blackman and Sebastiano Vigna (vigna@acm.org)
To the extent possible under law, the author has dedicated all copyright
and related and neighboring rights to this software to the public domain
worldwide.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
#include <stdint.h>
/* This is xoroshiro128++ 1.0, one of our all-purpose, rock-solid,
small-state generators. It is extremely (sub-ns) fast and it passes all
tests we are aware of, but its state space is large enough only for
mild parallelism.
For generating just floating-point numbers, xoroshiro128+ is even
faster (but it has a very mild bias, see notes in the comments).
The state must be seeded so that it is not everywhere zero. If you have
a 64-bit seed, we suggest to seed a splitmix64 generator and use its
output to fill s. */
static inline uint64_t rotl(const uint64_t x, int k) {
return (x << k) | (x >> (64 - k));
}
static uint64_t s[2];
uint64_t next(void) {
const uint64_t s0 = s[0];
uint64_t s1 = s[1];
const uint64_t result = rotl(s0 + s1, 17) + s0;
s1 ^= s0;
s[0] = rotl(s0, 49) ^ s1 ^ (s1 << 21); // a, b
s[1] = rotl(s1, 28); // c
return result;
}
/* This is the jump function for the generator. It is equivalent
to 2^64 calls to next(); it can be used to generate 2^64
non-overlapping subsequences for parallel computations. */
void jump(void) {
static const uint64_t JUMP[] = { 0x2bd7a6a6e99c2ddc, 0x0992ccaf6a6fca05 };
uint64_t s0 = 0;
uint64_t s1 = 0;
for(int i = 0; i < sizeof JUMP / sizeof *JUMP; i++)
for(int b = 0; b < 64; b++) {
if (JUMP[i] & UINT64_C(1) << b) {
s0 ^= s[0];
s1 ^= s[1];
}
next();
}
s[0] = s0;
s[1] = s1;
}
/* This is the long-jump function for the generator. It is equivalent to
2^96 calls to next(); it can be used to generate 2^32 starting points,
from each of which jump() will generate 2^32 non-overlapping
subsequences for parallel distributed computations. */
void long_jump(void) {
static const uint64_t LONG_JUMP[] = { 0x360fd5f2cf8d5d99, 0x9c6e6877736c46e3 };
uint64_t s0 = 0;
uint64_t s1 = 0;
for(int i = 0; i < sizeof LONG_JUMP / sizeof *LONG_JUMP; i++)
for(int b = 0; b < 64; b++) {
if (LONG_JUMP[i] & UINT64_C(1) << b) {
s0 ^= s[0];
s1 ^= s[1];
}
next();
}
s[0] = s0;
s[1] = s1;
}