1、有符号数与无符号数之间在运算之前,会先把有符号数都“转换”成/当成无符号数。例子:
int main() { int a = -1; unsigned int b = 2; cout << (a > b) << endl; // 1 cout << (a > 2) << endl; // 0。注意常数被当成有符号数 int c = -3; unsigned int d = 2; cout << c + d << endl; // 4294967295 cout << a + b << endl; // 1。a还是有被转换成无符号数! }
另一个例子:
#include <stdio.h> #define ELEMENT_COUNT (sizeof(array) / sizeof(array[0])) int array[] = {2, 3, 5, 7, 11, 13}; int main() { int d; for (d = -1; d <= (ELEMENT_COUNT - 2); d++) // d被转换为很大的无符号数,导致比较条件不成立,循环不会执行 printf("%d ", array[d + 1]); for (d = 0; d <= (ELEMENT_COUNT - 1); d++) // 输出2 3 5 7 11 13 printf("%d ", array[d]); return 0; }
对于有符号数,正数“取反加1”得到对应的负数。如:0x00000071(即113) -> 取反得到0xffffff8e -> 加1得到0xffffff8f(即-113)。
2、浮点数在内存中的表示(IEEE标准):
符号位bit数 | 指数位bit数/指数偏移量 | 小数部分bit数 | |
单精度浮点数 | 1 | 8/127 | 23 |
双精度浮点数 | 1 | 11/1023 | 52 |
以下是几个例子:
1)-12.5f的“转换”过程:-12.5f -> -(1100.1)2 -> “标准”形式-(1.1001 * 23)2。“标准”形式中有三部分(符号位、指数位和小数部分)需要保存:
(1)符号位为'-',因此第一个bit为(1)2;
(2)指数位为'3',加上偏移量127(8个bit的指数位只能表示0~255,因此可能为负的指数需要加上偏移量来保存)等于130,即(10000010)2;
(3)小数部分为'1001',为补全23个bit,填充19个0,因此小数部分是(10010000 00000000 0000000)2。
因此最终的二进制数为(11000001 01001000 00000000 00000000)2,即0xC1480000。
2)“转换”成整型:
float f = 12.5; // 0x41480000,即(1095237632)10 printf("%d ", (int)f); // 12 printf("%d ", *(int *)&f); // 1095237632。与(int &)f等价
3)求double的绝对值:
double ab(double y) { double x = y; *(((int *) &x) + 1) &= 0x7fffffff; // 只改变它的符号位。这里是小端模式(低字节保存在低地址) return x; }
不断学习中。。。