1. 信息的存储
a)
|
32 bit | 64 bit |
---|---|---|
char | 1 | 1 |
short int | 2 | 2 |
int | 4 | 4 |
long int | 4 | 8 |
long long int | 8 | 8 |
char* | 4 | 8 |
float | 4 | 4 |
double | 8 | 8 |
b)
0x01234567
地址: 0x100 0x101 0x102 0x103
little endian: ... 67 45 23 01
c)
// Code to print the byte representation of program objects. #include <stdio.h> typedef unsigned char *byte_pointer; 4 void show_bytes(byte_pointer start, int len) { int i; for (i = 0; i < len; i++) printf(" %.2x", start[i]); printf("\n"); } void show_int(int x) { show_bytes((byte_pointer) &x, sizeof(int)); } void show_float(float x) { show_bytes((byte_pointer) &x, sizeof(float)); } void show_pointer(void *x) { show_bytes((byte_pointer) &x, sizeof(void *)); }
2. 整数的表达
正负数的表达,负数是正数的补集(two's complement),
B2T4([0001]) = −0*2^3+0*2^2+0*2^1+1*2^0 =0+0+0+1=1
B2T4([0101]) = −0*2^3+1*2^2+0*2^1+1*2^0 =0+4+0+1=5
B2T4([1011]) = −1*2^3+0*2^2+1*2^1+1*2^0 = −8+0+2+1 = −5
B2T4([1111]) = −1*2^3+1*2^2+1*2^1+1*2^0 = −8+4+2+1 = −1
usigned int, 最高位是1的时候变成负数,最高位是0的时候是负数。
3. 整数的运算
4. 浮点数
类型 | 存储位数 | 偏移值 | ||||
数符(s) | 阶码(E) | 尾数(M) | 总位数 | 十六进制 | 十进制 | |
短实数(Single,Float) | 1位 | 8位 | 23位 | 32位 | 0x7FH | +127 |
长实数(Double) | 1位 | 11 位 | 52位 | 64位 | 0x3FFH | +1023 |
临时实数(延伸双精确度,不常用) | 1位 | 15位 | 64位 | 80位 | 0x3FFFH | +16383 |
F=1.M(二进制)
在单精度时: V=(-1)^s*2^(E-127)*F (127: 255的一半,一半用来表达小于0,一半用来大于0)
在双精度时: V=(-1)^s*2^(E-1023)*F
由于float的有无数个但是能表达的只有有限个, float在坐标轴上分布极其不均匀,越小越精确,越大越不精确,这也是浮点计算遇到大数更容易产生误差的原因,IEEE 定义了两大类五小类的近似标准。
Setting the hardware rounding mode to double precision prevents thisfrom happening:
$ gcc -Wall -DDOUBLE
1. Normalized
s≠0 &≠255f
2. Denormalized
s00000000 f
3a. Infinity
s1111111100000000000000000000000
3b. NaN
s11111111≠0
For argument f , it returns ±0 if f is denormalized (preserving the sign of f ) and returns f otherwise. /* If f is denorm, return 0. Otherwise, return f */ float_bits float_denorm_zero(float_bits f) { /* Decompose bit representation into parts */ unsigned sign = f>>31; unsigned exp = f>>23 & 0xFF; unsigned frac = f & 0x7FFFFF; if (exp == 0) { /* Denormalized. Set fraction to 0 */ frac = 0; } /* Reassemble bits */ return (sign << 31) | (exp << 23) | frac; }
具体的float如何运算,exception处理,和intel采用的是什么round方式,留以后研究。