【问题标题】:How is the expression "(a/b)*b + a%b - a" always zero in C for non-zero 'b'?对于非零'b',表达式“(a / b)* b + a%b - a”如何在C中始终为零?
【发布时间】:2014-09-21 14:55:42
【问题描述】:

以下内容摘自 Mike Banahan 和 Brady (Link: Section 2.8.2.1) 的 C 书籍。像我这样的普通人没有理由怀疑作者是错的,除非你们另有建议。

请告诉我 "(a/b)*b + a%b - a" 对于 b 不为零的整数如何始终为零。

提取的文本如下:

如果任一操作数为负数,则 / 的结果可能是最接近的 整数到两边的真实结果,以及结果的符号 % 可以是正数或负数。这两个特点都是 实现定义。

以下表达式等于零总是正确的:

    (a/b)*b + a%b - a

除非 b 为零。

通常的算术转换适用于两个操作数。

【问题讨论】:

  • 请注意,它是在 C89 中实现定义的。从 C99 开始,除法被定义为向 0 舍入(并且给定的等式仍然成立)。

标签: c type-conversion expression division modulo


【解决方案1】:

根据 C 中 % 运算符的定义,这是正确的。

C 标准中余数运算符的定义说:

(C11, 6.5.5p6) "如果商 a/b 是可表示的,则表达式 (a/b)*b + a%b 应等于 a;"

另请注意,对于/ 和%,如果第二个操作数是0,则标准将操作指定为未定义行为。

【讨论】:

  • 嗯......回答它......所有的肉......我正在尝试咀嚼......这需要一段时间才能消化...... +1。
  • 我从没想过这个例子会是标准的:O
  • @hacks 等一下……我是不是无意中在我的问题中提到了标准中的一个表达式? :-)
  • @hacks 你能看看我在问题stackoverflow.com/questions/25960878/…的第二次更新中问了什么
【解决方案2】:

数学上...

在纸面上,(a/b)*b == a (b cancels) 这就是结果看起来很有趣的原因。

但是,计算机首先计算 (a/b),然后乘以 b。如果这是在整数算术中完成的,那么 a/b 在乘法之前可能会向下舍入。

如果a

如果 a > b,则 (a/b)*b == floor(a/b) 和 (a/b)*b + a%b == a,再次给出 0。

本质上这是对编译器是否正确执行整数运算的测试

【讨论】:

  • +1。是的,数学解释更能说明问题。
  • a == INT_MIN 和 b == -1 有时会出现问题。
【解决方案3】:

如果 num1/num2 给出商 q 和余数 r,
然后num1 = q*num2 + r

这里将num1 作为a 和num2 作为b, 然后a/b 是商部分,余数部分是a%b。

所以a=(a/b)*b+(a%b) 和 (a/b)*b+(a%b)-a 等于 0

【讨论】:

    猜你喜欢
    • 2015-06-12
    • 2014-03-29
    • 2010-12-08
    • 2011-08-01
    • 2021-10-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-28
    相关资源
    最近更新 更多