贡献者: addis
1本文的模(modulo)运算都是指 $M$ 加减整数个 $N$ 后使结果范围在 $0$ 到 $N-1$ 之间(包含),$N$ 只能是正整数。本文中 $n$ 表示整数类型的比特数。
有符号整数类型的负数在内存中的二进制表示常采用 2 的补(2's complement)储存(例如 x86-64 架构)。若采用 2 的补,以下几点成立
也有其他表示负数的方法,例如最左边的 bit 表示符号,剩余表示大小。
数学上,可以将无符号的整数类型及其加法构成一个 $2^n$ 元循环群(见例 2 )。若采用 2 的补,由于群元素可以用任何符号,有符号整数类型可以看作将无符号整数类型的后一半元素减去 $2^n$,而群运算保持不变。
整数之间的转换规则:
memcpy()
函数。
其他基本类型转换规则:
bool
:0 变为 false
,否则变为 true
bool
转换为其他类型:true
变为 1,false
变为 0
signed
和 unsigned
整数之间比较大小或相等或时(如果开了 -Wall
,编译器会给出警告),前者会先转换为后者。这就导致负数有可能大于正数。做加减乘除时也一样,这叫做 usual arithmetic conversions。
bool, char, signed char, unsigned char, short, unsigned short
等,包括 11 以后的新标准加入的一些类型)参与二元运算如
+, -, *, /, %, &, |, ^, <<, >>, ==,
!=, <, >, <=, >=, +=, -=, *=, /=, %=,
&=, |=, ^=, <<=, >>=
以及 :?
的第二和第三个参数,会先转换为较大的整型,这就叫 integral promotion 或 integer promotion
int
可以表示该类型的全部范围,那么转换为 int
unsigned int
可以表示该类型的全部范围,那么转换为 unsigned int
unsigned
类型,那么就转换为 unsigned
类型,否则转换为 signed
类型。
2这里讨论 c++11 标准。literal 中的字母不区分大小写,0
开头表示 8 进制, 0x
开头表示 16 进制,数字后面可以加 u
,以及 l
或 ll
的一个(可以是大写)。literal 的类型会根据数值的大小而变化。
int
,最大是 long long int
每一种前面都可以加 unsigned
u
必定是 unsigned
u
的十进制必定是 signed,其他进制可以是 signed 或 unsigned(首选 signed)
l
和 ll
分别规定类型至少为 long
和 long long
,如果数值超出就不断升级
1. ^ 参考 C++ Primer [1]。
2. ^ 参考 cppreference。
[1] ^ S. B. Lippman, et al. C++ Primer 5th edition.