整数除法的行为是什么?

T.T*_*.T. 197 c math c99 integer-division c89

例如,

int result;

result = 125/100;
Run Code Online (Sandbox Code Playgroud)

要么

result = 43/100;
Run Code Online (Sandbox Code Playgroud)

结果总会成为师的底线吗?什么是定义的行为?

dir*_*tly 168

结果总会成为师的底线吗?什么是定义的行为?

是,两个操作数的整数商.

6.5.5乘法运算符

6当整数被分割时,/运算符的结果是代数商,丢弃任何小数部分.88)如果商a/b是可表示的,则表达式(a/b)*b + a%b应等于a.

以及相应的脚注:

88)这通常被称为"截断为零".

当然要注意的两点是:

3通常的算术转换是在操作数上执行的.

和:

5 /运算符的结果是第一个操作数除以第二个操作数的商; %运算符的结果是余数.在这两个操作中,如果第二个操作数的值为零,则行为未定义.

[注意:强调我的]

  • 它既不是地板也不是天花板,它是分数部分的截断,它在概念上是不同的! (69认同)
  • 至少从数学的角度来看,向零截断相当于"if> 0然后是其他上限." 我认为只是称它为截断比调用它/ floor是简单的,但要么是有效的.无论如何,威尔A的观点是有效的:Dirkgently的答案部分不正确,因为他表示OP对于结果是分区的结果是对的. (41认同)
  • @Will A:不.它被定义为截断为零.把它称之为其他东西只会增加混乱,所以请不要这样做. (33认同)
  • ...当然,除非您将负数除以正数(或vv),在这种情况下它将是上限. (21认同)
  • @Philip Potter:我不认为它是在C89中定义的,它不符合1998 C++标准.当然,那些'(a/b)*b + a%b == a`必须得到满足,而'a%b`的绝对值必须小于'a`,但是否是'a% b`为负的"a"或"b"为负,未指定. (8认同)
  • 为什么会有这么多的投票?它给出了错误的答案,然后引用了与答案直接矛盾的标准部分。是否可以根据截断定义截断并不重要。问题“结果将永远是部门的底线吗?”的答案 明确表示“不” (4认同)
  • 这种行为在C89中也是如此吗?我似乎记得模数没有严格定义. (2认同)
  • 即使将其定义为向零截断,在非负情况下仍为下限运算,在非正情况下仍为上限运算。它们是等效的定义。哪种定义更容易考虑取决于您在做什么。有时从地板和天花板的角度考虑更方便,有时从截断角度的角度考虑更方便。 (2认同)
  • 每个人都不断说“向零截断”或“天花板”或“地板”,就像代码正在深思熟虑地决定使用哪种技术一样。如果代码可以说话,它会说“我只是把大坝部分扔进垃圾桶,继续生活”` (2认同)

sch*_*hot 39

Dirkgently给出 C99中整数除法的优秀描述,但是您也应该知道在C89中,带有负操作数的整数除法具有实现定义的方向.

从ANSI C草案(3.3.5):

如果任一操作数为负,则/运算符的结果是小于代数商的最大整数还是大于代数商的最小整数是实现定义的,这是%运算符的结果的符号.如果商a/b是可表示的,则表达式(a/b)*b + a%b应等于a.

当你遇到C89编译器时,请注意负数.

这是一个有趣的事实,C99选择截断为零,因为这是FORTRAN如何做到的.请参阅comp.std.c上的此消息.

  • 而C99草案N1256前言第5段提到"可靠的整数除法"作为一种新的语言特征.惊人的`* - *`. (2认同)
  • @PeterCordes:大多数常见的CPU硬件可以通过大多数常量进行浮动除法,而不是截断除法.恕我直言,如果`expr1`的两个实例以相同的方式组合相同的对象,那么`expr1/expr2`和`expr1%expr2`必须相互一致才会更好. expr2`,但截断与覆盖除法的选择是否未指定.这样可以在不破坏太多兼容性的情况下实现更高效的代码生成(如果倾向于实现可以记录特定行为) (2认同)

小智 22

在结果为负的情况下,C截断为0而不是地板 - 我学习了这个解释为什么Python整数除法总是落在这里:为什么Python的整数分区Floors

  • +1对于为什么地板是整数除法的正确行为的一个很好的参考(与C的定义相反,它被破坏,几乎从不有用). (8认同)
  • 我同意这个评论,想知道是否(负%pos)消极是否有用?在相关的说明中,我想知道在"unsignedvar> signedvar"的某些情况下所需的算术错误行为是否有用?我可以理解不要求总是正确行为的理由; 我认为没有必要采取错误行为的理由. (3认同)

Leo*_*nid 20

是的,结果总是被截断为零.它将朝着最小的绝对值四舍五入.

-5 / 2 = -2
 5 / 2 =  2
Run Code Online (Sandbox Code Playgroud)

对于无符号和非负有符号值,这与floor(向-Infinity舍入)相同.

  • 截断,*不*楼层. (41认同)
  • @ dan04:yep floor只对正整数有效:) (9认同)

Muh*_*eeb 13

结果总会成为师的底线吗?

不会.结果会有所不同,但只有负值才会发生变化.

什么是定义的行为?

使整数分区朝向负无穷大,同时整数除法向零舍入(截断)

对于正值,它们是相同的

int integerDivisionResultPositive= 125/100;//= 1
double flooringResultPositive= floor(125.0/100.0);//=1.0
Run Code Online (Sandbox Code Playgroud)

对于负值,这是不同的

int integerDivisionResultNegative= -125/100;//=-1
double flooringResultNegative= floor(-125.0/100.0);//=-2.0
Run Code Online (Sandbox Code Playgroud)


adi*_*1ya 5

我知道人们已经回答了你的问题,但用外行的话来说:

5 / 2 = 2//因为5和2都是整数,并且整数除法总是截断小数

5.0 / 2 or 5 / 2.0 or 5.0 /2.0 = 2.5//这里5或2或两者都有小数,因此你得到的商将是小数。