update chapter2 homework
This commit is contained in:
parent
9d47a38269
commit
d30d50bad6
45
homework/chapter2/95.c
Normal file
45
homework/chapter2/95.c
Normal 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
73
homework/chapter2/97.c
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
@ -7,15 +7,30 @@
|
||||
|
||||
第二次操作,令 `x = x | (x >> 2)`,依次类推。通过 5 次操作即可实现提示中的转换。
|
||||
## 2.75
|
||||
$x,y$ 是无符号整数,$x'=U2T_w(x),y'=U2T_w(y)$。
|
||||
$x,y$ 是补码数,$x'=T2U_w(x),y'=T2U_w(y)$。
|
||||
|
||||
$$
|
||||
\begin{aligned}
|
||||
x'\times y'&=(x+x_{w-1}2^w)\times(y+y_{w-1}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+x_{w-1}\cdot 2^w)\times(y+y_{w-1}\cdot 2^w)\\
|
||||
&=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}$$
|
||||
|
||||
因此有 $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
|
||||
先得到粗糙的答案 `(x >> 2) + ((x >> 2) << 1)`,再根据 `x & 3` 进行修正。
|
||||
先得到粗糙的结果 `(x >> 2) + ((x >> 2) << 1)`,再根据 `x & 3` 以及 $x$ 的符号(决定舍入方向)进行修正。
|
||||
|
||||
## 2.97
|
||||
注意以下细节:
|
||||
- 使用“折半递归法”求 $i$ 的有效位数可以避免对于所有 $2^{32}$ 个 `int` 检验花费极长的时间;
|
||||
- 在某些情况下,舍入会导致有效位数增加。
|
Loading…
x
Reference in New Issue
Block a user