C 整数除法的行为是什么?

C 整数除法的行为是什么?,c,math,c99,c89,integer-division,C,Math,C99,C89,Integer Division,比如说, int result; result = 125/100; 或 结果永远是部门的地板吗?定义的行为是什么?是的,结果总是向零截断。它将向最小的绝对值进位 -5 / 2 = -2 5 / 2 = 2 对于无符号和非负符号值,这与floor(向-无穷大舍入)相同 结果永远是部门的地板吗?定义的行为是什么 不完全是。它向0而不是地板方向旋转 6.5.5乘法运算符 6当整数被除时,/运算符的结果是具有任意 如果商a/b是可表示的,则表达式 (a/b)*b+a%b应等于a 以及相应的脚

比如说,

int result;

result = 125/100;


结果永远是部门的地板吗?定义的行为是什么?

是的,结果总是向零截断。它将向最小的绝对值进位

-5 / 2 = -2
 5 / 2 =  2
对于无符号和非负符号值,这与floor(向-无穷大舍入)相同

结果永远是部门的地板吗?定义的行为是什么

不完全是。它向0而不是地板方向旋转

6.5.5乘法运算符

6当整数被除时,/运算符的结果是具有任意 如果商a/b是可表示的,则表达式 (a/b)*b+a%b应等于a

以及相应的脚注:

  • 这通常称为“向零截断”
  • 当然,有两点需要注意:

    3通常对操作数执行算术转换

    以及:

    5运算符的结果是 从函数的除法得到的商 第一个操作数乘以第二个操作数;这个 %运算符的结果是 剩余的。在这两种操作中,如果 第二个操作数的值为零, 该行为未定义


    [注意:我的重点]

    当结果为负数时,C向0截断,而不是向地板截断-我了解了关于Python整型除法为什么总是在这里地板的阅读:

    直接给出了C99中整型除法的值,但您还应该知道,在C89中,带负操作数的整数除法有一个实现定义的方向

    根据ANSI C草案(3.3.5):

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

    因此,当您使用C89编译器时,请注意负数

    有趣的是,C99选择了零截断,因为FORTRAN就是这样做的。见公司标准c

    结果永远是部门的地板吗

    不会。结果会发生变化,但变化只会发生在负值上

    定义的行为是什么

    为了清楚起见,地板朝负无穷大方向旋转,而整数除法朝零方向旋转(截断)

    对于正值,它们是相同的

    int integerDivisionResultPositive= 125/100;//= 1
    double flooringResultPositive= floor(125.0/100.0);//=1.0
    
    对于负值,这是不同的

    int integerDivisionResultNegative= -125/100;//=-1
    double flooringResultNegative= floor(-125.0/100.0);//=-2.0
    

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

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


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

    …当然,除非你将一个负数除以一个正数(或v.v.),在这种情况下,它将是天花板。它既不是地板也不是天花板,它是小数部分的截断,这在概念上是不同的@威尔A:不,它被定义为向零截断。称它为任何其他名称只会增加混乱,所以请不要这样做。至少从数学角度来看,向零截断相当于“如果>0,则为下限或上限”。我认为称它为截断比称它为下限/上限更简单,但两者都是有效的。无论如何,A的观点是否有效:DrkAltf的回答是部分错误的,因为他说OP是正确的关于结果是该分区的楼层。@ Philip Potter:我不认为它是在C89中定义的,它不是在1998 C++标准中。在这些情况下,当然必须满足
    (a/b)*b+a%b==a
    ,并且
    a%b
    的绝对值必须小于
    a
    ,但是没有指定
    a%b
    对于负
    a
    b
    是否为负。@dan04:yep floor仅对正整数有效:)我同意关于(负%pos)变为负是否有用的评论?另一方面,我想知道在“unsignedvar>signedvar”的某些情况下,所需的算术错误行为是否有用?我能理解不要求总是正确行为的理由;我看不出要求错误行为的理由。+1提供了一个很好的参考,说明为什么地板是整数除法的正确行为(与C的定义相反,C的定义是错误的,几乎从来没有用过)。@supercat考虑:
    filtered=(k-1)*filtered+value+carry;进位=过滤的%因子;过滤/=因子
    ,通过改变
    的值进行迭代。它对时间常数为
    k
    的一阶低通滤波器进行了很好的整数近似。。。但它只有在除法被截断并且进位得到负值时才是对称的。这两种除法行为有时都会派上用场。@hobbs:我认为当信号过零时,上面的代码不会表现得很干净。如果
    div
    是一个底层除法运算符,而
    factor
    是奇数,那么
    filtered+=(filter+(factor div 2))div factor
    将为所有小于
    INT_MAX-(factor div 2)
    的值产生干净对称的行为,尽管它确实有效;这段代码只是从我在原子钟控制器中运行了一段时间的代码中稍微提炼出来的。C99草案N1256前言第5段提到了可靠的整数除法作为一种新的语言功能。惊人的
    *-*
    。截断是最常见的CPU硬件(如x86)的行为方式,因此做出不同的选择是疯狂的。IDK是最先出现的,Fortran语义或硬件行为,但它们也是相同的,这并不是巧合。@PeterCordes:大多数常见的CPU硬件都可以做fl
    int integerDivisionResultNegative= -125/100;//=-1
    double flooringResultNegative= floor(-125.0/100.0);//=-2.0