基于 int 的最终答案
对于有符号整数:
int div = a / b;
if (((a ^ b) >= 0) && (a % b != 0))
div++;
对于无符号整数:
int div = a / b;
if (a % b != 0)
div++;
这个答案的原因
整数除法“/”被定义为向零舍入(规范的 7.7.2),但我们想要四舍五入。这意味着否定答案已经正确四舍五入,但肯定答案需要调整。
非零肯定答案很容易检测到,但答案为零有点棘手,因为它可以是负值的向上舍入或正值的向下舍入。
最安全的选择是通过检查两个整数的符号是否相同来检测答案何时应该是肯定的。在这种情况下,两个值的整数异或运算符“^”将导致符号位为 0,这意味着非负结果,因此检查 (a ^ b) >= 0 确定结果在舍入之前应该是正数。另请注意,对于无符号整数,每个答案显然都是肯定的,因此可以省略此检查。
剩下的唯一检查是是否发生了任何舍入,a % b != 0 将为此工作。
经验教训
算术(整数或其他)并不像看起来那么简单。任何时候都需要仔细思考。
此外,虽然我的最终答案可能不像浮点答案那样“简单”或“明显”甚至“快速”,但它对我来说具有很强的救赎品质;我现在已经对答案进行了推理,所以我实际上确信它是正确的(直到有更聪明的人告诉我不然——偷偷看向 Eric 的方向-)。
为了对浮点答案有同样的确定性,我必须做更多(并且可能更复杂)考虑是否存在浮点精度可能会妨碍的任何条件,并且Math.Ceiling 是否可能在“恰到好处”的输入上做了一些不受欢迎的事情。
走过的路
替换(请注意,我将第二个 myInt1 替换为 myInt2,假设这就是您的意思):
(int)Math.Ceiling((double)myInt1 / myInt2)
与:
(myInt1 - 1 + myInt2) / myInt2
唯一需要注意的是,如果myInt1 - 1 + myInt2 溢出了您正在使用的整数类型,您可能无法得到您期望的结果。
这是错误的原因:-1000000 和 3999 应该给出 -250,这给出 -249
编辑:
考虑到这与负 myInt1 值的其他整数解决方案具有相同的错误,因此执行以下操作可能更容易:
int rem;
int div = Math.DivRem(myInt1, myInt2, out rem);
if (rem > 0)
div++;
应该只使用整数运算在div 中给出正确的结果。
这是错误的原因:-1 和 -5 应该是 1,这应该是 0
编辑(再一次,带着感觉):
除法运算符向零舍入;对于阴性结果,这是完全正确的,因此只有非阴性结果需要调整。还考虑到 DivRem 只是做了一个 / 和一个 % 无论如何,让我们跳过调用(并从简单的比较开始,以避免在不需要时进行模计算):
int div = myInt1 / myInt2;
if ((div >= 0) && (myInt1 % myInt2 != 0))
div++;
这是错误的原因:-1 和 5 应该给出 0,这给出 1
(在我自己为最后一次尝试辩护时,我不应该在我的大脑告诉我我迟到了 2 小时睡觉时尝试了一个合理的答案)