2

从计算机系统:程序员的视角http://csapp.cs.cmu.edu

练习题 2.51

我们在习题 2.46 中看到爱国者导弹软件近似于 0.1,因为 x =

0.00011001100110011001100(binary). 

相反,假设他们使用 IEEE 舍入到偶数模式来确定 x' 到 0.1 的近似值,二进制点右侧有 23 位。

A. x' 的二进制表示是什么?

from the solution at the back of book, 
Looking at the nonterminating sequence for 1/10, we can see that the 2 bits to the right of the rounding position are 1, and so a better approximation to 1/10 would be obtained by incrementing x to get x′ = 0.00011001100110011001101, which is larger than 0.1.

B. x′ - 0.1 的近似十进制值是多少?

The solution says it's

We can see that x′ − 0.1 has binary representation: 0.0000000000000000000000000[1100]
Comparing this to the binary representation of 1 , we can see that it is 2^−22 × 0.1 , which is around 2.38 x 10^-8

我对(B)的问题是我们如何得到

x' - 0.1 == 0.0 0000 0000 0000 0000 0000 0000[1100] ?

我的计算给了我 0.000 0000 0000 0000 0000 0000 0100 (大约是解决方案所说的两倍)

4

3 回答 3

1

小数二进制表示中的0.1是:0.000[1100]

对于问题 2.46 中的近似值,在位置 23 之后有一个截止点,而在问题 2.51 中,一轮甚至发生在位置 23。后者意味着: - 要么 1) 去最接近的值 - 或 2) 如果正好在中间,去甚至。由于位置 24 ff 是11001100...情况 1),最接近的值是位置 23 变为 1 时。原始值和近似值的位:

x     = 0.0001100110011001100110011001100110011001100...
x_246 = 0.00011001100110011001100  # cutoff
x_251 = 0.00011001100110011001101  # round to even - as asked in A)

区别x' - 0.1,即x_251 - x,如B)中所要求的那样

  • 分数二进制

    x_251:   0.00011001100110011001101
    x:     - 0.0001100110011001100110011001100110011001100...
    fdiff:   0.0000000000000000000000000110011001100110011... or
    fdiff:   0.0 0000 0000 0000 0000 0000 0000[1100]
    
    --> this answers "question for (B) is that how do we get x' - 0.1 
          == 0.0 0000 0000 0000 0000 0000 0000[1100]"                            
    
  • 十进制值

    ddiff = (1*2^-26 + 1*2^-27) + (1*2^-30 + A1*2^-31) + (...) + ...
          =     3*2^-27         +     3*2^-31         +    3*2^-35 + ...
          = 0.1*2^-22 = 2.384e-8  (sum of geometric serie)
    julia> @printf "%.40f" 0.1*2.0^-22
    0.0000000238418579101562513234889800848443
    

题外话:为什么julia> @printf "%.40f" 0.1f0和上面的小数差ddiff有区别?

0.1000000014901161193847656250000000000000
0.0000000238418579101562513234889800848443

0.1f0表示为IEEE 浮点值。位 ( julia> bits(f0.1f0)) ("00111101110011001100110011001101") 具有以下含义:

0 01111011 10011001100110011001101
| |        | M = 1 + f
| | E = e - Bias = 123 - 127 = -4 --> V = M*2^-4 (right shift M by 4)
| sign

M:         1.10011001100110011001101
M/sh: 0.0001.10011001100110011001101
x_shifted: 0.000110011001100110011001101
x_251:     0.00011001100110011001101

--> 0.1 的移位近似值比 x_251 多 4 位。差的十进制值x_shifted - x(如上计算)给出:0.1*2^-26。现在这两种表示适合:

    julia> @printf "%.40f" 0.1*2.0^-26
    0.0000000014901161193847657077180612553028
    0.1000000014901161193847656250000000000000  # julia> @printf "%.40f" 0.1f0
于 2017-11-30T12:35:01.460 回答
0

使用 Julia

一个。

julia> bits(0.1f0)
"00111101110011001100110011001101"

B. 我们无法精确计算差值(因为没有原生的小数类型),但您可以精确打印小数,然后手动减去

julia> @printf "%.40f" 0.1f0
0.1000000014901161193847656250000000000000

所以区别是0.0000000014901161193847656250000000000000 = 1.490116119384765625e-9

于 2014-12-09T11:56:11.023 回答
0

我也有同样的困惑。您可以尝试通过从解决方案向后思考来理解给定的解决方案。

0.1 +the given solution

= 0.000 1100 1100 1100...+0.00000000000000000000000001100 1100 1100...

=0.000 1100 1100 1100 1100 1100 1111 1111 1111...

观察到上面的结果是我们可以做的最好的近似x' = 0.000 1100 1100 1100 1100 1101

于 2021-07-30T00:57:04.023 回答