试图还原老师讲课的思路。
Background: Fractional binary numbers
怎样表示小数?
一种是fixed point number;一种是float point number
定点数,顾名思义,小数点是固定的,能表示的整数位数m和小数位数n是固定的;
浮点数,更加自由,小数点可以移动,虽然m+n一定,但是m和n都是可以变化的,可以表示的数的范围更大。
IEEE floating point standard: Definition
Sign bit s determines whether number is negative or positive
Significand M normally a fractional value in range [1.0,2.0)
Exponent E weights value by power of two
sign bit s
exp field encodes E (but is not equal to E)
frac field encodes M (but is not equal to M)
实际上就是科学计数法。这样表示也适合计算移位。
为甚么选择科学计数法?
1.大数、小数都方便表示;2.方便保留有效数字(significant figure)
保留有效数字时我们希望四舍五入,这时候我们需要补偿精度。
我们希望也能表示负数,需要将指数部分也进行一个bias。比如说3位数,能表示0~7,为了能表示负数,让0成为中心,减去3,变成-3~4
Bias = 2^(k-1) - 1
E = Exp – Bias
Single precision: 127 (E: -126…127)
Double precision: 1023 (E: -1022…1023)
举个例子,
float F = 15213.0; (4字节,32 bit)
1521310 = 111011011011012
= 1.11011011011012 x 2^13
s,符号位:
s=0 表示正数 (1 bit)
Significand,有效数字:
M = 1.1101101101101 除了0以外,其他数都是1打头,所以M只存小数部分。
frac = 1101101101101 0000000000 (23 bit)
Exponent,指数部分:
E = 13
Bias = 127
Exp = 140 = 10001100 (8 bit)
下面我们看一个c语言里float的Decoding:
float: 0xC0A00000
binary: 1100 0000 1010 0000 0000 0000 0000 0000
E = 129 -> Exp = 129 – 127 = 2 (decimal)
S = 1 -> negative number
M = 1.010 0000 0000 0000 0000 0000
= 1 + 1/4 = 1.25
Example and properties
按照上述规则,咱们看一个8bit的浮点数怎么表示:
首先第一位是符号位,然后4bit是指数部分,然后3bit是小数位,Bias=2^(4-1)-1=7.
这样的好处是能带来一个Dynamic Range,同时可以表示负数。
Rounding, addition, multiplication
round默认采用Nearest Even,也就是四舍五入。这里指数部分决定了保留多少位有效数字。下面举一些例子说明二进制round是怎么做的:
比如nearest 1/4
浮点数相乘:
举例,
浮点数加法:
举个例子,
Floating point in C
C有两种表示:
float: 单精度
Double: 双精度
转换:
double/float → int: 截断小数部分,rounding
int → double: 精确转换,因为整数的位数<52
int → float; rounding
所以记住,当你在计算机里用不同的方法计算同一个式子时,得到的结果不一定相同,会有一个误差。下式都是不一定成立的:
(int x; float f; double d;)
x == (int)(float) x
d == (double)(float) d
2/3 == 2/3.0
(d+f)-d == f
下面展示了一些浮点数的表示,注意一下0和1:
这节课主要讲了硬件里浮点数的表示,计算。说实话,自己没有搞得太清楚。等学一段时间再返回来咀嚼。