[C][C运算][取模/取余运算][隐式类型转换][算术转换]详细讲解
[C][C运算][取模/取余运算][隐式类型转换][算术转换]详细讲解
·
1.取模/取余运算
1.取整
- C语言默认向0取整 –
trunc()
同作用 floor()
-> 向-∞
取整ceil()
-> 向+∞
取整round()
-> 四舍五入
2.取模
- 定义:如果
a
和d
是两个自然数,d
非零,可以证明存在两个唯一的整数q
和r
,满足 a = q ∗ d + r a = q*d + r a=q∗d+r ,q
为整数,且 0 ≤ ∣ r ∣ < ∣ d ∣ 0 ≤ |r| < |d| 0≤∣r∣<∣d∣,q
被称为商,r
被称为余数 - 取模和取余一样吗?
- 不能严格等价,但大部分情况差不多
- 取整:
- 取余:尽可能让商,进行向0取整
- 取模:尽可能让商,向-∞方向取整
- **C中
%
本质是取余 - 对任何一个
> 0
的数,对其进行0向取整和-∞取整,取整方向是一致的- 故取模等价于取余
- 对任何一个
< 0
的数,对其进行0向取整和-∞取整,取整方向是相反的- 故取模不等价于取余
- 符号:
- 参与取余的两个数据,如果同符号,取模等价于取余
- 若参与运算的数据不同符号
- 如果参与取余的两个数据符号不同,在C语言中,余数符号,与被除数相同
2.隐式类型转换
- C的整形算术运算总是至少以缺省整形类型的精度来进行的
- 整型提升:为了获得这个精度,表达式中的
char
和short
操作数在使用之前会被转化为int
- 整形提升的意义:
- 表达式的整形运算要在CPU的相应运算器件内执行,CPU内整形运算器(ALU)的操作数的字节长度一般就是
int
的字节长度,同时也是CPU的通用寄存器的长度 - 因此,即使两个
char
类型的相加,在CPU执行时实际上也要先转化为CPU内int
的标准长度 - 通用CPU是难以直接实现两个
8 bit
字节直接相加运算(虽然机器指令中可能有这种字节相加指令)- 所以,表达式中各种长度可能小于
int
长度的整型值,都必须先转换为int
或unsigned int
,然后才能送入CPU去执行运算
- 所以,表达式中各种长度可能小于
- 表达式的整形运算要在CPU的相应运算器件内执行,CPU内整形运算器(ALU)的操作数的字节长度一般就是
- 例子:
b
和c
的值被提升为int
,然后再执行加法运算- 加法运算完成之后,结果将被截断,然后再存储于
a
中
char a, b, c;
...
a = b + c;
- 如何进行整形提升?
- 整形提升是按照变量的数据类型的符号位来提升的
- 负数的整型提升:
char c1 = -1;
- 变量
c1
的二进制位(补码):11111111
- 因为
char
为有符号的char
- 所以整型提升的时候,高位补符号位
1
- 提升后的结果为
11111111111111111111111111111111
- 所以整型提升的时候,高位补符号位
- 变量
- 正数的整型提升:
char c2 = 1;
- 变量
c2
的二进制位(补码):00000001
- 因为
char
为有符号的char
- 所以整型提升的时候,高位补符号位
0
- 提升后的结果为
00000000000000000000000000000001
- 所以整型提升的时候,高位补符号位
- 变量
3.算术转换
- 如果某个**操作符的各个操作数属于不同的类型**,那么除非其中一个操作数转换为另一个操作数的类型,否则操作就无法进行
- 下面的层次体系称为寻常算术转换
- 如果某个操作数的类型在下面这个列表中排名较低,那么首先要转换为另外一个操作数的类型,然后再执行运算
long double
double
float
unsigned long
long
unsigned int
int
- 但是算数转换要合理,否则会有一些潜在的问题
float f = 3.14;
int num = f; // 隐式转换,会有精度丢失
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
已为社区贡献7条内容
所有评论(0)