C中的除法,商和余数的大小、符号如何确定
对于C中的除法,商和余数的大小、符号是如何确定的呢?在C89中,只规定了如果两个数为正整数,那么余数的符号为正,并且商的值是接近真实值的最大整数。比如5 / 2,那么商就是2,余数就是1。但是,C89里面对于被除数和除数里面,有负整数时,商的大小以及余数的符号没有做出明确的规定,而只是说这依赖于具体实现。在Windows下(是Intel汇编指令),看如下如下例子:
int main() { int a = -5; int b = a / 3; }
接下来看汇编码:
; 1 : int main() { push ebp mov ebp, esp sub esp, 8 ; 2 : int a = -5; mov DWORD PTR _a$[ebp], -5 ; fffffffbH ; 3 : int b = a / 3; mov eax, DWORD PTR _a$[ebp] cdq mov ecx, 3 idiv ecx ;idiv执行有符号的除法,并且余数的符号和被除数一样 mov DWORD PTR _b$[ebp], eax ; 4 : }
汇编码中,最重要的就是idiv指令,这个指令运行后的结果是余数的符号会保持和被除数一样,同时,对于除法来说,余数的绝对值要小于除数的绝对值,这样,我们就可以确定商、余数的大小以及符号。对于上面的例子-5 / 3来说,商就是-1,余数就是-2。
有时,由于除法可以转换成加减法以及算数右移来执行,汇编码不会用到idiv指令(这可以看成是一种优化),但是结果不会有影响,比如看下面的-5 / 2的汇编指令,就没有用到idiv,但是结论和上面一样,商是-2,余数是-1:
; 1 : int main() { push ebp mov ebp, esp sub esp, 8 ; 2 : int a = -5; mov DWORD PTR _a$[ebp], -5 ; fffffffbH ; 3 : int b = a / 2; mov eax, DWORD PTR _a$[ebp] cdq sub eax, edx sar eax, 1 ;算数右移操作 mov DWORD PTR _b$[ebp], eax ; 4 : ; 5 : }
上面的结论在Linux下(AT&T风格的汇编)同样成立,虽然汇编码和Intel汇编不一样。
另外,C89中规定,对于%取余运算符,只适用于整型
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了