跟随,为公共帐户加注星标,直接访问精彩内容。 C语言的负数除以正数,而正数除以负数或负数除以负数的余数和商,由谁决定正负? -3 / 2 =? ; -3%2 =?; 3 /(-2)= ;; 3%(-2)= ;; (-3)/(-2)=? (-3)%(-2)=?;假设假设我们用b除以,商为q,余数为r:q = a / b; r = a%b;在这里,让我们假设b大于0。我们希望在a,b,q和r之间保持什么样的关系?最重要的一点是我们希望q * b + r == a,因为这是定义余数的关系。如果我们改变a的符号,我们希望这将改变q的符号,但是不会改变q& nbsp;的绝对值。当b& gt; 0时,我们要确保r& gt == 0和r< lt; 0。 b。例如,如果其余部分用于哈希表的索引,则重要的是要确保它是有效的索引值。这三个属性是我们认为整数除法和余数运算应具有的属性。不幸的是,它们不能同时为真。示例考虑一个简单的示例:3/2,商为1,余数也为1。这时,满足第一个性质。 (-3)/ 2的值应该是什么?如果满足第二个属性,则答案应为-1,但如果满足,则余数必须为-1,因此无法满足第三个属性。如果我们首先满足第三个属性,即余数为1,在这种情况下,根据第一个属性,商为-2,则无法满足第二个属性。因此,在执行整数除法截断运算时,C语言或其他语言必须至少放弃上述三种原理之一。大多数编程语言都选择放弃第3条,而发现其余部分与分红的符号相同。这样,可以满足属性1和属性2。大多数C编译器实际上都是这样做的。但是,C语言的定义仅保证属性1,而当a& = 0且b& gt; 0时,它保证| r |。 & lt; | b |并且r = 0。后一部分中的保证比自然2或自然3的约束要少得多。示例说明尽管C语言的定义有时会带来不必要的灵活性,但是在大多数情况下,只要程序员清楚地知道该做什么和该做什么就可以了。确实,此定义仍然是为了使整数除法运算满足其需求。足够的。例如,假设我们有一个数字n,它代表标识符中字符的某些功能运算的结果,并且我们希望通过除法运算获得哈希表的条目h,该数字满足0-1。 h< HASHSIZE。而且,如果我们知道n始终为非负数,那么我们只需要简单地编写如下:h = n%HASHSIZE:但是,如果n可能为负,并且此时h也可能为负,则不是案子。它必须始终是适当的。但是,我们知道h> -HASHSIZE,因此我们可以这样写:h = n%HASHSIZE; if(n& lt; 0)h + = HASHSIZE;测试代码:#include< stdio.h& gt; main(){int a = -3,b = 2,c = 3,d = -2; int q,r,m,n,x,y; q = a / b; r = a%b; m = c / d; n = c%d; x = a / d; y = a%d; printf(“ q =%d,r =%d
" q,r); printf(“ m =%d,n =%d
,, m,n); printf(“ x =%d,y =%d
&quot ;, x,y);}的最终结论是,这个问题在C语言的早期并未得到解决。因此,在某些书中,此行为的值是不确定的,这是由编译器确定的,但是现在C99中有一项强制性要求,要求必须满足a%b == a-(a / b)b对于整数a和b。如果第一个操作数为负,则获得的模数为负;否则,为0。如果第一个操作数为正,则获得的模数为正。因此,当您遇到这样的问题时,通常的计算方法是:余数与除数相同(即分子的符号);首先将所有带符号的数字取正值,然后进行除法,然后根据负号的数量确定商的符号。当然,在实际项目中,最好避免在设计程序时避免n值为负的情况,并声明n为无符号数。推荐读物(单击标题跳转以阅读)[编程的美]使用C语言实现状态机(实用)[编程的美]超时重传,滑动窗口,可靠的传输原理C语言实现[编程的美] ]关于嵌入式架构的重要性