update chapter2 homework
This commit is contained in:
parent
94b39e92b8
commit
8ae7b4b9e9
@ -1,23 +0,0 @@
|
|||||||
#include <assert.h>
|
|
||||||
#include <limits.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;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main() {
|
|
||||||
for (unsigned x = 0; ; x++) {
|
|
||||||
assert(odd_ones(x) == __builtin_parity(x));
|
|
||||||
|
|
||||||
if (x == UINT_MAX) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,30 +0,0 @@
|
|||||||
#include <assert.h>
|
|
||||||
#include <limits.h>
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main() {
|
|
||||||
for (unsigned x = 0; ; x++) {
|
|
||||||
assert((x == 0 && leftmost_one(x) == 0) || (x != 0 && leftmost_one(x) == (1 << (31 - __builtin_clz(x)))));
|
|
||||||
|
|
||||||
if (x == UINT_MAX) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,31 +0,0 @@
|
|||||||
#include <limits.h>
|
|
||||||
#include <assert.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
int signed_high_prod(int x, int y) {
|
|
||||||
long long p = (long long) x * y;
|
|
||||||
return p >> 32;
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned randu() {
|
|
||||||
if (rand() & 1) {
|
|
||||||
return rand();
|
|
||||||
} else {
|
|
||||||
return ~rand();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int main() {
|
|
||||||
assert(RAND_MAX == INT_MAX);
|
|
||||||
|
|
||||||
const int test_cases = 1e8;
|
|
||||||
for (int i = 0; i < test_cases; i++) {
|
|
||||||
unsigned x = randu(), y = randu();
|
|
||||||
assert((unsigned long long) x * y == ((unsigned long long) unsigned_high_prod(x, y) << 32) + x * y);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,26 +0,0 @@
|
|||||||
#include <assert.h>
|
|
||||||
#include <limits.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
int threefourths(int x) {
|
|
||||||
int p = x >> 2, q = x & 3;
|
|
||||||
return p + (p << 1) + q - ((!!q & (~x >> 31)) & 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
int randi() {
|
|
||||||
if (rand() & 1) {
|
|
||||||
return rand();
|
|
||||||
} else {
|
|
||||||
return ~rand();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int main() {
|
|
||||||
assert(RAND_MAX == INT_MAX);
|
|
||||||
|
|
||||||
const int test_cases = 1e8;
|
|
||||||
for (int i = 0; i < test_cases; i++) {
|
|
||||||
int x = randi();
|
|
||||||
assert(threefourths(x) == (long long) x * 3 / 4);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,45 +0,0 @@
|
|||||||
#include <assert.h>
|
|
||||||
#include <math.h>
|
|
||||||
#include <limits.h>
|
|
||||||
|
|
||||||
/* Access bit-level representation of floating-point number */
|
|
||||||
typedef unsigned float_bits;
|
|
||||||
|
|
||||||
/* 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--;
|
|
||||||
return s | (e << 23) | f;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (e == 1) {
|
|
||||||
f |= 1 << 23;
|
|
||||||
e = 0;
|
|
||||||
}
|
|
||||||
int t = f;
|
|
||||||
f >>= 1;
|
|
||||||
if (t & f & 1) {
|
|
||||||
f++;
|
|
||||||
}
|
|
||||||
return s | (e << 23) | f;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main() {
|
|
||||||
for (float_bits x = 0; ; x++) {
|
|
||||||
float *a = (float*) &x;
|
|
||||||
float b = 0.5 * *a;
|
|
||||||
float_bits c = float_half(x);
|
|
||||||
float *d = (float*) &c;
|
|
||||||
assert(b == *d || (isnan(b) && isnan(*d)));
|
|
||||||
|
|
||||||
if (x == UINT_MAX) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,56 +0,0 @@
|
|||||||
#include <assert.h>
|
|
||||||
#include <limits.h>
|
|
||||||
|
|
||||||
/* Access bit-level representation of floating-point number */
|
|
||||||
typedef unsigned float_bits;
|
|
||||||
|
|
||||||
/* Compute (float) i */
|
|
||||||
float_bits float_i2f(int i) {
|
|
||||||
if (i == INT_MIN) {
|
|
||||||
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;
|
|
||||||
if (hb > 23) {
|
|
||||||
f = i >> (hb - 23);
|
|
||||||
if ((i & (1 << (hb - 24))) && ((f & 1) || (i & ((1 << (hb - 24)) - 1)))) {
|
|
||||||
f++;
|
|
||||||
if (f & 0x00800000) {
|
|
||||||
f = 0;
|
|
||||||
e++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
f = i << (23 - hb);
|
|
||||||
}
|
|
||||||
|
|
||||||
return s | (e << 23) | f;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main() {
|
|
||||||
for (int x = INT_MIN; ; x++) {
|
|
||||||
float_bits y = float_i2f(x);
|
|
||||||
float *z = (float*) &y;
|
|
||||||
assert(*z == (float) x);
|
|
||||||
|
|
||||||
if (x == INT_MAX) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
13
homework/chapter2/Makefile
Normal file
13
homework/chapter2/Makefile
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
#
|
||||||
|
# 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
|
2
homework/chapter2/README
Normal file
2
homework/chapter2/README
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
第二章作业 65、66、75、80、95 和 97 的测试框架。你需要编辑 homework.c 中的六个函数完成作业,然后输入命令 make 编译程序,输入命令 ./test 查看结果。
|
||||||
|
homework_sample.c 中有参考实现。
|
104
homework/chapter2/homework.c
Normal file
104
homework/chapter2/homework.c
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
#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;
|
||||||
|
}
|
104
homework/chapter2/homework_sample.c
Normal file
104
homework/chapter2/homework_sample.c
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
#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;
|
||||||
|
}
|
40
homework/chapter2/main.c
Normal file
40
homework/chapter2/main.c
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
#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");
|
||||||
|
}
|
||||||
|
}
|
101
homework/chapter2/test.c
Normal file
101
homework/chapter2/test.c
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
#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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
26
homework/chapter2/test.h
Normal file
26
homework/chapter2/test.h
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
#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
|
97
homework/chapter2/xoroshiro128plusplus.c
Normal file
97
homework/chapter2/xoroshiro128plusplus.c
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
/* 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;
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user