first commit

This commit is contained in:
2025-03-06 19:56:12 +08:00
commit 5b6db97133
47 changed files with 8549 additions and 0 deletions

47
datalab/README.txt Normal file
View File

@@ -0,0 +1,47 @@
数据实验
你的目标是修改bits.c文件使得其能够通过btest测试并确保不违反任何编程要求
***********************************************************
1. 修改bits.c并使用dlc来检查编程要求
***********************************************************
请仔细阅读bits.c文件中的要求其中指明了你需要遵守的编程要求。
*************************************
2. 使用btest来测试你的程序的正确性
*************************************
在lcc中新建一个工程名字叫做btest
将下列文件添加入工程:
bits.c
btest.c
decl.c
getopt.c
tests.c
编译将会生成一个btest.exe可执行文件
运行btest.exe
btest.exe [optional command line arguments]
*******************
3. btest做了什么
*******************
btest程序将通过一系列数据来测试你的bits.c是否正确。
btest的一些命令行参数
-e <N> 限制对某个函数的报错数目为N缺省该参数将会无限制
-f <Name> 检查特定名字的函数
-g 打印出简要信息(等同于 -v 0 和 -e 0)
-h 显示本信息
-a 不检查分组
-r <N> 对所有问题设置相同的权重N
-v <N> 设置显示级别为 N
N=0: 仅仅给出最终得分
N=1: N=1 另外还给出单项得分(缺省值)

BIN
datalab/datalab.pdf Normal file

Binary file not shown.

16
datalab/src/Makefile Executable file
View File

@@ -0,0 +1,16 @@
CC = gcc
CFLAGS = -O -Wall -m32
LIBS = -lm
all: btest
btest: btest.c bits.c decl.c tests.c getopt.c getopt.h btest.h bits.h
$(CC) $(CFLAGS) $(LIBS) -o btest bits.c btest.c decl.c tests.c getopt.c
run: btest
./btest
clean:
rm -f *.o btest

326
datalab/src/bits.c Normal file
View File

@@ -0,0 +1,326 @@
/*
* CS:APP Data Lab
*
* bits.c - <20><>ʵ<EFBFBD><CAB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD>޸ı<DEB8><C4B1>ļ<EFBFBD><C4BC><EFBFBD>
* <20><><EFBFBD><EFBFBD>Ҫ<EFBFBD>Ѵ<EFBFBD><D1B4>ļ<EFBFBD><C4BC><EFBFBD><E1BDBB><EFBFBD><EFBFBD>ʦ/<2F≯<EFBFBD><CCB8><EFBFBD>
*
*/
#include "btest.h"
#include <limits.h>
/*
* ѧ<><D1A7><EFBFBD><EFBFBD>ʵ<EFBFBD><CAB5>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD>
*
* <20><><EFBFBD><EFBFBD>1<EFBFBD><31><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֡<EFBFBD>ѧ<EFBFBD><D1A7><EFBFBD><EFBFBD>д<EFBFBD><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ľṹ<C4BD>У<EFBFBD>
*/
team_struct team = {
/* Replace this with your full name */
"程景愉",
/* Replace this with your Andrew login ID */
"202302723005"};
#if 0
/*
* <20><><EFBFBD><EFBFBD>2<EFBFBD><32><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϸ<EFBFBD>Ķ<EFBFBD><C4B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˵<EFBFBD><CBB5><EFBFBD><EFBFBD>
*/
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD><EFBFBD><E9A3AC>ͨ<EFBFBD><CDA8><EFBFBD><EFBFBD><E0BCAD><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD>bits.c<><63><EFBFBD>еĸ<D0B5><C4B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E1BDBB><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><EFBFBD>
<09><><EFBFBD><EFBFBD>return<72><6E><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E6BBBB>һ<EFBFBD>л<EFBFBD><D0BB>߶<EFBFBD><DFB6><EFBFBD>ʵ<EFBFBD>ֺ<EFBFBD><D6BA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܵ<EFBFBD>C<EFBFBD><43><EFBFBD>
<09><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>/<2F>޸ĵĴ<C4B5><C4B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ķ<EFBFBD><C4B7>
int Funct(arg1, arg2, ...) {
/* <20><>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD>ָú<D6B8><C3BA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܵ<EFBFBD> */
int var1 = Expr1;
...
int varM = ExprM;
varJ = ExprJ;
...
varN = ExprN;
return ExprR;
}
ÿһ<C3BF><D2BB><EFBFBD><EFBFBD>Expr<70><72><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><CAB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݵı<DDB5><C4B1><EFBFBD>ʽ<EFBFBD><CABD>
1. 0~255<35><35>0xFF<46><46><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD>ô<EFBFBD>ij<EFBFBD><C4B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>0xffffffff<66><66>
2. <20><><EFBFBD><EFBFBD><EFBFBD>IJ<EFBFBD><C4B2><EFBFBD><EFBFBD>;ֲ<CDBE><D6B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><CAB9>ȫ<EFBFBD>ֱ<EFBFBD><D6B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
3. <20><>Լ<EFBFBD><D4BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>" ! ~ "
4. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> & ^ | + << >> <20><>
һЩ<D2BB><D0A9><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD>֣<EFBFBD><D6A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܹ<EFBFBD>ʹ<EFBFBD>õ<EFBFBD><C3B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
ÿһ<C3BF><D2BB><EFBFBD><EFBFBD>Expr<70><72><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʽ<EFBFBD><CABD><EFBFBD>ܰ<EFBFBD><DCB0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>û<EFBFBD><C3BB>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ÿ<EFBFBD><C3BF>ֻ<EFBFBD><D6BB>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<09><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϸ<EFBFBD><CFB8>ֹ<EFBFBD><D6B9>
1. ʹ<><CAB9><EFBFBD>κο<CEBA><CEBF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E4A3AC><EFBFBD><EFBFBD>if, do, while, for, switch, <20>ȵȡ<C8B5>
2. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><CAB9><EFBFBD>κκꡣ
3. <20>ڴ<EFBFBD><DAB4>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>κζ<CEBA><CEB6><EFBFBD>ĺ<EFBFBD><C4BA><EFBFBD><EFBFBD><EFBFBD>
4. <20><><EFBFBD><EFBFBD><EFBFBD>κκ<CEBA><CEBA><EFBFBD><EFBFBD><EFBFBD>
5. ʹ<><CAB9><EFBFBD>κ<EFBFBD><CEBA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> &&, ||, -, <20><><EFBFBD><EFBFBD> ?:
6. ʹ<><CAB9><EFBFBD>κ<EFBFBD><CEBA><EFBFBD>ʽ<EFBFBD><CABD>ǿ<EFBFBD><C7BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ת<EFBFBD><D7AA><EFBFBD><EFBFBD>
<20><><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><C4B5>ԣ<EFBFBD>
1. ʹ<><CAB9>2<EFBFBD>IJ<EFBFBD><C4B2>룬32λ<32><CEBB>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
2. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
3. <20><><EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD><CEBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֳ<EFBFBD><D6B3><EFBFBD><EFBFBD><EFBFBD>ô<EFBFBD><C3B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ԥ<EFBFBD><D4A4>Ľ<EFBFBD><C4BD><EFBFBD><EFBFBD>
// <20><><EFBFBD>Խ<EFBFBD><D4BD>ܵı<DCB5>̷<EFBFBD><CCB7><EFBFBD>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD>
/*
* pow2plus1 - returns 2^x + 1, where 0 <= x <= 31
*/
int pow2plus1(int x) {
/* exploit ability of shifts to compute powers of 2 */
return (1 << x) + 1;
}
/*
* pow2plus4 - returns 2^x + 4, where 0 <= x <= 31
*/
int pow2plus4(int x) {
/* exploit ability of shifts to compute powers of 2 */
int result = (1 << x);
result += 4;
return result;
}
ע<EFBFBD>
1. <20><><EFBFBD><EFBFBD>ʹ<EFBFBD><CAB9>dlc.exe<78><65><EFBFBD><EFBFBD><EFBFBD><EFBFBD>bits.c<>Ƿ<EFBFBD><C7B7><EFBFBD>ϱ<EFBFBD><CFB1>Ҫ<EFBFBD><D2AA>
2. Each function has a maximum number of operators (! ~ & ^ | + << >>)
that you are allowed to use for your implementation of the function.
The max operator count is checked by dlc. Note that '=' is not
counted; you may use as many of these as you want without penalty.
3. ʹ<><CAB9>btest<73><74><EFBFBD><EFBFBD><EFBFBD>ĺ<EFBFBD><C4BA><EFBFBD><EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD>ȷ<EFBFBD><C8B7>
4. The maximum number of ops for each function is given in the
header comment for each function. If there are any inconsistencies
between the maximum ops in the writeup and in this file, consider
this file the authoritative source.
#endif
/*
* <20><><EFBFBD><EFBFBD>3:
* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ı<EFBFBD><C4B1>Ҫ<EFBFBD><D2AA><EFBFBD>޸<EFBFBD><DEB8><EFBFBD><EFBFBD><EFBFBD>ĺ<EFBFBD><C4BA><EFBFBD><EFBFBD><EFBFBD>
*
* <20><>Ҫ<EFBFBD><D2AA>Ϊ<EFBFBD>˱<EFBFBD><CBB1><EFBFBD>ܲ<EFBFBD>ijɼ<C4B3><C9BC><EFBFBD>
* 1. ʹ<><CAB9>dlc.exe<78><65><EFBFBD><EFBFBD><EFBFBD>ı<EFBFBD>̷<EFBFBD><CCB7><EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA>
* 2.
* ʹ<><CAB9>btest<73><74><EFBFBD><EFBFBD><EFBFBD>ĺ<EFBFBD><C4BA><EFBFBD><EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD>ȷ<EFBFBD><C8B7><EFBFBD><EFBFBD>ע<EFBFBD><D7A2><EFBFBD><EFBFBD>Tmin<69><6E>Tmax<61><78><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD>ȷ<EFBFBD><C8B7>
*/
/*
* bitAnd - x&y using only ~ and |
* Example: bitAnd(6, 5) = 4
* Legal ops: ~ |
* Max ops: 8
* Rating: 1
*/
int bitAnd(int x, int y) {
// 实现x&y的位与运算
return x & y;
}
/*
* bitXor - x^y using only ~ and &
* Example: bitXor(4, 5) = 1
* Legal ops: ~ &
* Max ops: 14
* Rating: 2
*/
int bitXor(int x, int y) { return 2; }
/*
* evenBits - return word with all even-numbered bits set to 1
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 8
* Rating: 2
*/
int evenBits(void) { return 2; }
/*
* getByte - Extract byte n from word x
* Bytes numbered from 0 (LSB) to 3 (MSB)
* Examples: getByte(0x12345678,1) = 0x56
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 6
* Rating: 2
*/
int getByte(int x, int n) { return 2; }
/*
* bitMask - Generate a bitmask consisting of all 1's
* from lowbit to highbit and 0's everywhere else.
* Examples: bitMask(5,3) = 0x38
* Assume 0 <= lowbit <= 31, and 0 <= highbit <= 31
* If lowbit > highbit, then mask should be all 0's
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 16
* Rating: 3
*/
int bitMask(int highbit, int lowbit) {
// 生成从lowbit到highbit的位掩码
if (lowbit > highbit)
return 0;
else {
int res = 0;
for (int i = lowbit; i <= highbit; i++) {
res |= (1 << i);
}
return res;
}
}
/*
* reverseBytes - reverse the bytes of x
* Example: reverseBytes(0x01020304) = 0x04030201
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 25
* Rating: 3
*/
int reverseBytes(int x) {
// 提取每个字节并移动到正确的位置
int byte0 = (x >> 24) & 0xFF; // 提取最高字节并移动到最低字节位置
int byte1 = (x >> 8) & 0xFF00; // 提取第二字节并移动到第二字节位置
int byte2 = (x << 8) & 0xFF0000; // 提取第三字节并移动到第三字节位置
int byte3 = (x << 24); // 提取最低字节并移动到最高字节位置
// 将各个字节合并
return byte0 | byte1 | byte2 | byte3;
}
/*
* leastBitPos - return a mask that marks the position of the
* least significant 1 bit. If x == 0, return 0
* Example: leastBitPos(96) = 0x20
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 6
* Rating: 4
*/
int leastBitPos(int x) {
// 根据补码是取反再加一的性质
return x & (~x + 1);
}
/*
* logicalNeg - implement the ! operator, using all of
* the legal operators except !
* Examples: logicalNeg(3) = 0, logicalNeg(0) = 1
* Legal ops: ~ & ^ | + << >>
* Max ops: 12
* Rating: 4
*/
int logicalNeg(int x) { return 2; }
/*
* minusOne - return a value of -1
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 2
* Rating: 1
*/
int minusOne(void) {
// 1的补码0直接取反
return ~0;
}
/*
* TMax - return maximum two's complement integer
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 4
* Rating: 1
*/
int tmax(void) { return 2; }
/*
* negate - return -x
* Example: negate(1) = -1.
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 5
* Rating: 2
*/
int negate(int x) { return ~x + 1; }
/*
* isPositive - return 1 if x > 0, return 0 otherwise
* Example: isPositive(-1) = 0.
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 8
* Rating: 3
*/
int isPositive(int x) { return 2; }
/*
* isLess - if x < y then return 1, else return 0
* Example: isLess(4,5) = 1.
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 24
* Rating: 3
*/
int isLess(int x, int y) { return 2; }
/*
* sm2tc - Convert from sign-magnitude to two's complement
* where the MSB is the sign bit
* Example: sm2tc(0x80000005) = -5.
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 15
* Rating: 4
*/
int sm2tc(int x) { return 2; }
/*
* getHighBit - return a mask that marks the position of the
* most significant 1 bit. If x == 0, return 0
* Legal ops: ! ~ & ^ | + << >>
*/
int getHighBit(int x) {
// 使用位运算找到最高位
return x & (~(x - 1));
}
/*
* getLowBit - return a mask that marks the position of the
* least significant 1 bit. If x == 0, return 0
* Legal ops: ! ~ & ^ | + << >>
*/
int getLowBit(int x) {
// 使用位运算找到最低位
return x & (~x + 1);
}
/*
* isNegative - return 1 if x < 0, return 0 otherwise
* Legal ops: ! ~ & ^ | + << >>
*/
int isNegative(int x) {
// 判断符号位
return (x >> 31) & 1;
}
/*
* isGreater - if x > y then return 1, else return 0
* Legal ops: ! ~ & ^ | + << >>
*/
int isGreater(int x, int y) {
// 判断x是否大于y
return (x - y) > 0;
}
/*
* tmin - return minimum two's complement integer
* Legal ops: ! ~ & ^ | + << >>
*/
int tmin(void) {
// 返回最小的二补数
return 1 << 31;
}
/*
* plusOne - return x + 1
* Legal ops: ! ~ & ^ | + << >>
*/
int plusOne(int x) {
// 实现加1操作
return x + 1;
}

114
datalab/src/bits.h Normal file
View File

@@ -0,0 +1,114 @@
int bitAnd(int a, int b);
int test_bitAnd(int, int);
int bitXor(int, int);
int test_bitXor(int, int);
int evenBits();
int test_evenBits();
int getByte(int, int);
int test_getByte(int, int);
int bitMask(int, int);
int test_bitMask(int, int);
int reverseBytes(int);
int test_reverseBytes(int);
int leastBitPos(int);
int test_leastBitPos(int);
int logicalNeg(int);
int test_logicalNeg(int);
int minusOne();
int test_minusOne();
int tmax();
int test_tmax();
int negate(int);
int test_negate(int);
int isPositive(int);
int test_isPositive(int);
int isLess(int, int);
int test_isLess(int, int);
int sm2tc(int);
int test_sm2tc(int);

BIN
datalab/src/btest Executable file

Binary file not shown.

318
datalab/src/btest.c Normal file
View File

@@ -0,0 +1,318 @@
/*
* CS:APP Data Lab
*
* btest.c - A test harness that checks a student's solution
* in bits.c for correctness.
*
* Copyright (c) 2001, R. Bryant and D. O'Hallaron, All rights reserved.
* May not be used, modified, or copied without permission.
*
* Usage:
* -e <N> 限制对某个函数的报错数目为N缺省该参数将会无限制
* -f <Name> 检查特定名字的函数
* -g 打印出简要信息(等同于 -v 0 和 -e 0)
* -h 显示本信息
* -a 不检查分组
* -r <N> 对所有问题设置相同的权重N
* -v <N> 设置显示级别为 N
* N=0: 仅仅给出最终得分
* N=1: N=1 另外还给出单项得分(缺省值)
*
* Each problem has a weight 1 to 4, which is defined in legallist.c.
*/
#include <stdio.h>
// #include <unistd.h>
#include "btest.h"
#include "getopt.h"
#include <limits.h>
#include <stdlib.h>
#include <string.h>
/* Globals defined in other modules */
extern team_struct team; /* defined in bits.c */
extern test_rec test_set[]; /* defined in decl.c */
/* and generated from templates in ./puzzles */
/* Generate test values near "corner cases" */
#define TEST_RANGE 5
#define TEST_COUNT 33
/* Print only compact grading summary if set (-g) */
static int grade = 0;
/* Max errors reported per function (-e) */
static int error_limit = 1000;
/* If non-NULL, test only one function (-f) */
static char *test_fname = NULL;
/* Should I used fixed weight for rating, and if so, what should it be? (-r)*/
static int global_rating = 0;
/* Return random value between min and max */
static int random_val(int min, int max) {
double weight = rand() / (double)RAND_MAX;
int result = min * (1 - weight) + max * weight;
return result;
}
/* Generate the integer values we'll use to test a function */
static int gen_vals(int test_vals[], int min, int max) {
int i;
int test_count = 0;
/* If range small enough, then do exhaustively */
if (max - 32 <= min) {
for (i = min; i <= max; i++)
test_vals[test_count++] = i;
return test_count;
}
/* Otherwise, need to sample.
Do so near the boundaries and for a few random cases */
for (i = 0; i < TEST_RANGE; i++) {
test_vals[test_count++] = min + i;
test_vals[test_count++] = max - i;
test_vals[test_count++] = (max + min - TEST_RANGE) / 2 + i;
test_vals[test_count++] = random_val(min, max);
}
return test_count;
}
/* Test a function with zero arguments */
static int test_0_arg(funct_t f, funct_t ft, char *name, int report) {
int r = f();
int rt = ft();
int error = (r != rt);
if (error && report)
;
// printf("测试 %s() 失败!\n 计算得到 %d[0x%x]. 应该是 %d[0x%x]\n",
// name, r, r, rt, rt);
return error;
}
/* Test a function with one argument */
static int test_1_arg(funct_t f, funct_t ft, int arg1, char *name, int report) {
funct1_t f1 = (funct1_t)f;
funct1_t f1t = (funct1_t)ft;
int r, rt, error;
r = f1(arg1);
rt = f1t(arg1);
error = (r != rt);
if (error && report)
// printf("测试 %s(%d[0x%x]) 失败!\n 计算得到 %d[0x%x]. 应该是
// %d[0x%x]\n",
// name, arg1, arg1, r, r, rt, rt);
;
return error;
}
/* Test a function with two arguments */
static int test_2_arg(funct_t f, funct_t ft, int arg1, int arg2, char *name,
int report) {
funct2_t f2 = (funct2_t)f;
funct2_t f2t = (funct2_t)ft;
int r = f2(arg1, arg2);
int rt = f2t(arg1, arg2);
int error = (r != rt);
if (error && report)
// printf("测试 %s(%d[0x%x],%d[0x%x]) 失败!\n 计算得到 %d[0x%x]. 应该是 "
// "%d[0x%x]\n",
// name, arg1, arg1, arg2, arg2, r, r, rt, rt);
;
return error;
}
/* Test a function with three arguments */
static int test_3_arg(funct_t f, funct_t ft, int arg1, int arg2, int arg3,
char *name, int report) {
funct3_t f3 = (funct3_t)f;
funct3_t f3t = (funct3_t)ft;
int r = f3(arg1, arg2, arg3);
int rt = f3t(arg1, arg2, arg3);
int error = (r != rt);
if (error && report)
// printf("测试 %s(%d[0x%x],%d[0x%x],%d[0x%x]) 失败!\n 计算得到 %d[0x%x].
// "
// "应该是 %d[0x%x]\n",
// name, arg1, arg1, arg2, arg2, arg3, arg3, r, r, rt, rt);
;
return error;
}
/* Test a function. Return number of errors */
static int test_function(test_ptr t, int report) {
int test_vals[3][TEST_COUNT];
int test_counts[3];
int errors = 0;
int i;
int a1, a2, a3;
int args = t->args;
/* Create test set */
for (i = 0; i < 3; i++)
test_counts[i] =
gen_vals(test_vals[i], t->arg_ranges[i][0], t->arg_ranges[i][1]);
if (args == 0) {
errors += test_0_arg(t->solution_funct, t->test_funct, t->name,
report && errors < error_limit);
} else
for (a1 = 0; a1 < test_counts[0]; a1++) {
if (args == 1) {
errors += test_1_arg(t->solution_funct, t->test_funct, test_vals[0][a1],
t->name, report && errors < error_limit);
} else
for (a2 = 0; a2 < test_counts[1]; a2++) {
if (args == 2) {
errors += test_2_arg(t->solution_funct, t->test_funct,
test_vals[0][a1], test_vals[1][a2], t->name,
report && errors < error_limit);
} else
for (a3 = 0; a3 < test_counts[2]; a3++) {
errors +=
test_3_arg(t->solution_funct, t->test_funct, test_vals[0][a1],
test_vals[1][a2], test_vals[2][a3], t->name,
report && errors < error_limit);
}
}
}
if (!grade) {
if (report && errors > error_limit)
printf("函数 %s 总共有%d个错误\n", t->name, errors);
}
return errors;
}
/* Run series of tests. Return number of errors */
static int run_tests(int report) {
int i;
int errors = 0;
double points = 0.0;
double max_points = 0.0;
if (grade)
printf("得分\t错误数\t函数\n");
for (i = 0; test_set[i].solution_funct; i++) {
int terrors;
double tscore;
double tpoints;
if (!test_fname || strcmp(test_set[i].name, test_fname) == 0) {
int rating = global_rating ? global_rating : test_set[i].rating;
terrors = test_function(&test_set[i], report);
errors += terrors;
if (test_set[i].args == 0)
tscore = terrors == 0 ? 1.0 : 0.0;
else
tscore = terrors == 0 ? 1.0 : terrors == 1 ? 0.5 : 0.0;
tpoints = rating * tscore;
points += tpoints;
max_points += rating;
if (grade)
printf(" %.1f\t%d\t%s\n", tpoints, terrors, test_set[i].name);
if (report)
printf("测试 %s 得分: %.2f/%.2f\n", test_set[i].name, tpoints,
(double)rating);
}
}
if (grade)
printf("总分: %.2f/%.2f\n", points, max_points);
else
printf("总共正确得分: %.2f/%.2f\n", points, max_points);
return errors;
}
static void usage(char *cmd) {
printf("Usage: %s [-v 0|1] [-hag] [-f <func name>] [-e <max errors>]\n", cmd);
printf(" -e <n> 限制对某个函数的报错数目为n缺省该参数将会无限制\n");
printf(" -f <name> 检查特定名字的函数\n");
printf(" -g 打印出简要信息(等同于 -v 0 和 -e 0)\n");
printf(" -h 显示本信息\n");
printf(" -a 不检查分组\n");
printf(" -r <n> 对所有问题设置相同的权重n\n");
printf(" -v <n> 设置显示级别为 n\n");
printf(" n=0: 仅仅给出最终得分\n");
printf(" n=1: 另外还给出单项得分(缺省值)\n");
exit(1);
}
/*
* main routine
*/
int main(int argc, char *argv[]) {
int verbose_level = 1;
int errors;
int team_check = 1;
char c;
/* parse command line args */
while ((c = getopt(argc, argv, "hagv:f:e:r:")) != -1)
switch (c) {
case 'h': /* help */
usage(argv[0]);
break;
case 'a': /* Don't check team structure */
team_check = 0;
break;
case 'g': /* grading summary */
grade = 1;
break;
case 'v': /* set verbosity level */
verbose_level = atoi(optarg);
if (verbose_level < 0 || verbose_level > 1)
usage(argv[0]);
break;
case 'f': /* test only one function */
test_fname = strdup(optarg);
break;
case 'e': /* set error limit */
error_limit = atoi(optarg);
if (error_limit < 0)
usage(argv[0]);
break;
case 'r': /* set global rating for each problem */
global_rating = atoi(optarg);
if (global_rating < 0)
usage(argv[0]);
break;
default:
usage(argv[0]);
}
if (grade) {
error_limit = 0;
verbose_level = 0;
}
if (team_check) {
if ((*team.name1 == '\0') || (*team.id1 == '\0')) {
printf("%s: 错误!你必须填写所有小组成员!\n", argv[0]);
exit(1);
} else
printf("学生:\t%s\t%s\n", team.name1, team.id1);
printf("\n");
}
/* test each function */
errors = run_tests(verbose_level > 0);
if (!grade) {
if (errors > 0)
printf("发现%d个错误\n", errors);
else {
printf("成功通过所有测试!\n");
}
}
return 0;
}

39
datalab/src/btest.h Normal file
View File

@@ -0,0 +1,39 @@
/*
* CS:APP Data Lab
*/
/*
* Students work in teams of one. They enter their name and ID
* in a struct of this type in their bits.c file.
*/
typedef struct {
char *name1; /* full name */
char *id1; /* Andrew ID */
} team_struct;
/* Declare different function types */
typedef int (*funct_t) (void);
typedef int (*funct1_t)(int);
typedef int (*funct2_t)(int, int);
typedef int (*funct3_t)(int, int, int);
/* Combine all the information about a function and its tests as structure */
typedef struct {
char *name;
funct_t solution_funct; /* These will typically be casted */
funct_t test_funct;
int args;
char *ops;
int op_limit;
int rating;
int arg_ranges[3][2]; /* Min & Max values for each argument */
} test_rec, *test_ptr;
extern test_rec test_set[];

137
datalab/src/decl.c Normal file
View File

@@ -0,0 +1,137 @@
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#define TMin LONG_MIN
#define TMax LONG_MAX
#include "btest.h"
#include "bits.h"
test_rec test_set[] = {
{"bitAnd", (funct_t) bitAnd, (funct_t) test_bitAnd, 2, "| ~", 8, 1,
{{TMin, TMax},{TMin,TMax},{TMin,TMax}}},
{"bitXor", (funct_t) bitXor, (funct_t) test_bitXor, 2, "& ~", 14, 2,
{{TMin, TMax},{TMin,TMax},{TMin,TMax}}},
{"evenBits", (funct_t) evenBits, (funct_t) test_evenBits, 0,
"! ~ & ^ | + << >>", 8, 2,
{{TMin, TMax},{TMin,TMax},{TMin,TMax}}},
{"getByte", (funct_t) getByte, (funct_t) test_getByte, 2,
"! ~ & ^ | + << >>", 6, 2,
{{TMin, TMax},{0,3},{TMin,TMax}}},
{"bitMask", (funct_t) bitMask, (funct_t) test_bitMask, 2,
"! ~ & ^ | + << >>", 16, 3,
{{0, 31},{0,31},{TMin,TMax}}},
{"reverseBytes", (funct_t) reverseBytes, (funct_t) test_reverseBytes, 1,
"! ~ & ^ | + << >>", 25, 3,
{{TMin, TMax},{TMin,TMax},{TMin,TMax}}},
{"leastBitPos", (funct_t) leastBitPos, (funct_t) test_leastBitPos, 1, "! ~ & ^ | + << >>", 6, 4,
{{TMin, TMax},{TMin,TMax},{TMin,TMax}}},
{"logicalNeg", (funct_t) logicalNeg, (funct_t) test_logicalNeg, 1,
"~ & ^ | + << >>", 12, 4,
{{TMin, TMax},{TMin,TMax},{TMin,TMax}}},
{"minusOne", (funct_t) minusOne, (funct_t) test_minusOne, 0,
"! ~ & ^ | + << >>", 2, 1,
{{TMin, TMax},{TMin,TMax},{TMin,TMax}}},
{"tmax", (funct_t) tmax, (funct_t) test_tmax, 0, "! ~ & ^ | + << >>", 4, 1,
{{TMin, TMax},{TMin,TMax},{TMin,TMax}}},
{"negate", (funct_t) negate, (funct_t) test_negate, 1,
"! ~ & ^ | + << >>", 5, 2,
{{TMin, TMax},{TMin,TMax},{TMin,TMax}}},
{"isPositive", (funct_t) isPositive, (funct_t) test_isPositive, 1,
"! ~ & ^ | + << >>", 8, 3,
{{TMin, TMax},{TMin,TMax},{TMin,TMax}}},
{"isLess", (funct_t) isLess, (funct_t) test_isLess, 2,
"! ~ & ^ | + << >>", 24, 3,
{{TMin, TMax},{TMin,TMax},{TMin,TMax}}},
{"sm2tc", (funct_t) sm2tc, (funct_t) test_sm2tc, 1, "! ~ & ^ | + << >>", 15, 4,
{{TMin, TMax},{TMin,TMax},{TMin,TMax}}},
{"", NULL, NULL, 0, "", 0, 0,
{{0, 0},{0,0},{0,0}}}
};

254
datalab/src/getopt.c Normal file
View File

@@ -0,0 +1,254 @@
#define _CRT_SECURE_NO_WARNINGS 1
/*****************************************************************************
* getopt.c - competent and free getopt library.
* $Header: /cvsroot/freegetopt/freegetopt/getopt.c,v 1.2 2003/10/26 03:10:20 vindaci Exp $
*
* Copyright (c)2002-2003 Mark K. Kim
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the original author of this software nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "getopt.h"
//static const char* ID = "$Id: getopt.c,v 1.2 2003/10/26 03:10:20 vindaci Exp $";
char* optarg = NULL;
int optind = 0;
int opterr = 1;
int optopt = '?';
static char** prev_argv = NULL; /* Keep a copy of argv and argc to */
static int prev_argc = 0; /* tell if getopt params change */
static int argv_index = 0; /* Option we're checking */
static int argv_index2 = 0; /* Option argument we're checking */
static int opt_offset = 0; /* Index into compounded "-option" */
static int dashdash = 0; /* True if "--" option reached */
static int nonopt = 0; /* How many nonopts we've found */
static void increment_index(void);
static int permute_argv_once(void);
static void increment_index(void)
{
/* Move onto the next option */
if(argv_index < argv_index2)
{
while(prev_argv[++argv_index] && prev_argv[argv_index][0] != '-'
&& argv_index < argv_index2+1);
}
else argv_index++;
opt_offset = 1;
}
/*
* Permutes argv[] so that the argument currently being processed is moved
* to the end.
*/
static int permute_argv_once(void)
{
/* Movability check */
if(argv_index + nonopt >= prev_argc) return 1;
/* Move the current option to the end, bring the others to front */
else
{
char* tmp = prev_argv[argv_index];
/* Move the data */
memmove(&prev_argv[argv_index], &prev_argv[argv_index+1],
sizeof(char**) * (prev_argc - argv_index - 1));
prev_argv[prev_argc - 1] = tmp;
nonopt++;
return 0;
}
}
int getopt(int argc, char** argv, char* optstr)
{
int c = 0;
/* If we have new argv, reinitialize */
if(prev_argv != argv || prev_argc != argc)
{
/* Initialize variables */
prev_argv = argv;
prev_argc = argc;
argv_index = 1;
argv_index2 = 1;
opt_offset = 1;
dashdash = 0;
nonopt = 0;
}
/* Jump point in case we want to ignore the current argv_index */
getopt_top:
/* Misc. initializations */
optarg = NULL;
/* Dash-dash check */
if(argv[argv_index] && !strcmp(argv[argv_index], "--"))
{
dashdash = 1;
increment_index();
}
/* If we're at the end of argv, that's it. */
if(argv[argv_index] == NULL)
{
c = -1;
}
/* Are we looking at a string? Single dash is also a string */
else if(dashdash || argv[argv_index][0] != '-' || !strcmp(argv[argv_index], "-"))
{
/* If we want a string... */
if(optstr[0] == '-')
{
c = 1;
optarg = argv[argv_index];
increment_index();
}
/* If we really don't want it (we're in POSIX mode), we're done */
else if(optstr[0] == '+' || getenv("POSIXLY_CORRECT"))
{
c = -1;
/* Everything else is a non-opt argument */
nonopt = argc - argv_index;
}
/* If we mildly don't want it, then move it back */
else
{
if(!permute_argv_once()) goto getopt_top;
else c = -1;
}
}
/* Otherwise we're looking at an option */
else
{
char* opt_ptr = NULL;
/* Grab the option */
c = argv[argv_index][opt_offset++];
/* Is the option in the optstr? */
if(optstr[0] == '-') opt_ptr = strchr(optstr+1, c);
else opt_ptr = strchr(optstr, c);
/* Invalid argument */
if(!opt_ptr)
{
if(opterr)
{
fprintf(stderr, "%s: invalid option -- %c\n", argv[0], c);
}
optopt = c;
c = '?';
/* Move onto the next option */
increment_index();
}
/* Option takes argument */
else if(opt_ptr[1] == ':')
{
/* ie, -oARGUMENT, -xxxoARGUMENT, etc. */
if(argv[argv_index][opt_offset] != '\0')
{
optarg = &argv[argv_index][opt_offset];
increment_index();
}
/* ie, -o ARGUMENT (only if it's a required argument) */
else if(opt_ptr[2] != ':')
{
/* One of those "you're not expected to understand this" moment */
if(argv_index2 < argv_index) argv_index2 = argv_index;
while(argv[++argv_index2] && argv[argv_index2][0] == '-');
optarg = argv[argv_index2];
/* Don't cross into the non-option argument list */
if(argv_index2 + nonopt >= prev_argc) optarg = NULL;
/* Move onto the next option */
increment_index();
}
else
{
/* Move onto the next option */
increment_index();
}
/* In case we got no argument for an option with required argument */
if(optarg == NULL && opt_ptr[2] != ':')
{
optopt = c;
c = '?';
if(opterr)
{
fprintf(stderr,"%s: option requires an argument -- %c\n",
argv[0], optopt);
}
}
}
/* Option does not take argument */
else
{
/* Next argv_index */
if(argv[argv_index][opt_offset] == '\0')
{
increment_index();
}
}
}
/* Calculate optind */
if(c == -1)
{
optind = argc - nonopt;
}
else
{
optind = argv_index;
}
return c;
}
/* vim:ts=3
*/

63
datalab/src/getopt.h Normal file
View File

@@ -0,0 +1,63 @@
/*****************************************************************************
* getopt.h - competent and free getopt library.
* $Header: /cvsroot/freegetopt/freegetopt/getopt.h,v 1.2 2003/10/26 03:10:20 vindaci Exp $
*
* Copyright (c)2002-2003 Mark K. Kim
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the original author of this software nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*/
#ifndef GETOPT_H_
#define GETOPT_H_
#ifdef __cplusplus
extern "C" {
#endif
extern char* optarg;
extern int optind;
extern int opterr;
extern int optopt;
int getopt(int argc, char** argv, char* optstr);
#ifdef __cplusplus
}
#endif
#endif /* GETOPT_H_ */
/* vim:ts=3
*/

175
datalab/src/tests.c Normal file
View File

@@ -0,0 +1,175 @@
/* Testing Code */
#include <limits.h>
int test_bitAnd(int x, int y)
{
return x&y;
}
int test_bitXor(int x, int y)
{
return x^y;
}
int test_evenBits(void) {
int result = 0;
int i;
for (i = 0; i < 32; i+=2)
result |= 1<<i;
return result;
}
int test_getByte(int x, int n)
{
union {
int word;
unsigned char bytes[4];
} u;
int test = 1;
int littleEndian = (int) *(char *) &test;
u.word = x;
return littleEndian ? (unsigned) u.bytes[n] : (unsigned) u.bytes[3-n];
}
int test_bitMask(int highbit, int lowbit)
{
int result = 0;
int i;
for (i = lowbit; i <= highbit; i++)
result |= 1 << i;
return result;
}
int test_reverseBytes(int x)
{
union U {
int result;
char byte[4];
};
union U u;
int temp;
u.result = x;
temp = u.byte[0];
u.byte[0] = u.byte[3];
u.byte[3] = temp;
temp = u.byte[1];
u.byte[1] = u.byte[2];
u.byte[2] = temp;
return u.result;
}
int test_leastBitPos(int x) {
int mask = 1;
if (x == 0)
return 0;
while (!(mask & x)) {
mask = mask << 1;
}
return mask;
}
int test_logicalNeg(int x)
{
return !x;
}
int test_minusOne(void) {
return -1;
}
int test_tmax(void) {
return LONG_MAX;
}
int test_negate(int x) {
return -x;
}
int test_isPositive(int x) {
return x > 0;
}
int test_isLess(int x, int y)
{
return x < y;
}
int test_sm2tc(int x) {
int sign = x < 0;
int mag = x & LONG_MAX;
return sign ? -mag : mag;
}

Binary file not shown.