update chapter2 homework

This commit is contained in:
18218461270@163.com 2025-07-23 20:30:58 +08:00
parent 9d47a38269
commit d30d50bad6
3 changed files with 138 additions and 5 deletions

45
homework/chapter2/95.c Normal file
View File

@ -0,0 +1,45 @@
#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 & 0x80000000U, f = uf & 0x007FFFFF, e = (uf >> 23) & 0xFF;
if (e == 0xFFU) {
return uf;
}
if (e > 1) {
e = e - 1;
return s | (e << 23) | f;
}
if (e == 1) {
f = f | (1 << 23);
e = 0;
}
int t = f;
f = f >> 1;
if (t & f & 1) {
f = f + 1;
}
return s | (e << 23) | f;
}
int main() {
for (float_bits x = 0; ; x = x + 1) {
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;
}
}
}

73
homework/chapter2/97.c Normal file
View File

@ -0,0 +1,73 @@
#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 0xCF000000U;
}
if (i == 0) {
return 0;
}
float_bits s = 0, f, e;
if (i < 0) {
i = -i;
s = 0x80000000U;
}
int hb = 0, t = i;
if (t >> 16) {
t = t >> 16;
hb = hb + 16;
}
if (t >> 8) {
t = t >> 8;
hb = hb + 8;
}
if (t >> 4) {
t = t >> 4;
hb = hb + 4;
}
if (t >> 2) {
t = t >> 2;
hb = hb + 2;
}
if (t >> 1) {
t = t >> 1;
hb = hb + 1;
}
i = 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 = f + 1;
if (f & 0x00800000U) {
f = 0;
e = e + 1;
}
}
} else {
f = i << (23 - hb);
}
return s | (e << 23) | f;
}
int main() {
for (int x = INT_MIN; ; x = x + 1) {
float_bits y = float_i2f(x);
float *z = (float*) &y;
assert(*z == (float) x);
if (x == INT_MAX) {
break;
}
}
}

View File

@ -7,15 +7,30 @@
第二次操作,令 `x = x | (x >> 2)`,依次类推。通过 5 次操作即可实现提示中的转换。 第二次操作,令 `x = x | (x >> 2)`,依次类推。通过 5 次操作即可实现提示中的转换。
## 2.75 ## 2.75
$x,y$ 是无符号整数,$x'=U2T_w(x),y'=U2T_w(y)$。 $x,y$ 是补码数,$x'=T2U_w(x),y'=T2U_w(y)$。
$$ $$
\begin{aligned} \begin{aligned}
x'\times y'&=(x+x_{w-1}2^w)\times(y+y_{w-1}2^w)\\ x'\cdot y'&=(x+x_{w-1}\cdot 2^w)\times(y+y_{w-1}\cdot 2^w)\\
&=x\times y+(x_{w-1}\times y+y_{w-1}\times x)2^w+x_{w-1}y_{w-1}2^{2w} &=x\cdot y+(x_{w-1}\cdot y+y_{w-1}\cdot x)2^w+x_{w-1}\cdot y_{w-1}\cdot 2^{2w}
\end{aligned}$$ \end{aligned}$$
因此有 $U2B_{2w}(x'\times y')=T2B_{2w}(x\times y+(x_{w-1}\times y+y_{w-1}\times x)2^w)$。即令 `a = signed_high_prod(x, y), b = unsigned_high_prod(x', y')`$T2B_w(a+x_{w-1}\times y+y_{w-1}\times x)=U2B_w(b)$。 进一步,令 `a = signed_high_prod(x, y), b = unsigned_high_prod(x', y')`,有
$$b\cdot 2^w+x'*^u_w y'=a\cdot 2^w+T2U_w(x*^t_wy)+(x_{w-1}\cdot y+y_{w-1}\cdot x)2^w+x_{w-1}\cdot y_{w-1}\cdot 2^{2w}$$
化简得
$$b=a+x_{w-1}\cdot y+y_{w-1}\cdot x+x_{w-1}\cdot y_{w-1}\cdot 2^w$$
$$\begin{aligned}
b&=(a+x_{w-1}\cdot y+y_{w-1}\cdot x)\bmod 2^w\\
&=T2U_w(a)+^u_t x_{w-1}\cdot y'+^u_t y_{w-1}\cdot x'
\end{aligned}$$
## 2.80 ## 2.80
先得到粗糙的答案 `(x >> 2) + ((x >> 2) << 1)`,再根据 `x & 3` 进行修正。 先得到粗糙的结果 `(x >> 2) + ((x >> 2) << 1)`,再根据 `x & 3` 以及 $x$ 的符号(决定舍入方向)进行修正。
## 2.97
注意以下细节:
- 使用“折半递归法”求 $i$ 的有效位数可以避免对于所有 $2^{32}$ 个 `int` 检验花费极长的时间;
- 在某些情况下,舍入会导致有效位数增加。