我偶然发现了
int a = (h/2)*w+ ( (h+1)/2-h/2 ) * (w+1)/2 ;
等于
int b = (w * h + 1) / 2 ;
当w和h是正整数时(假设没有溢出)。
你能告诉我为什么这两个是一样的吗?
编辑:整数 - >正整数。
答案 0 :(得分:8)
为了简化表达,您必须考虑四种情况:
从那里开始,并应用适当的整数截断规则,您应该能够简化为第二个表达式。
答案 1 :(得分:7)
实际上这是一个数学问题:(整数)/ 2应该被解释为floor。所以,问题是:
显示
floor(h/2)*w + ( floor((h+1)/2) - floor(h/2) ) * floor((w+1)/2)
等同于floor((w*h+1)/2)
证明:
提示:floor((2k+1)/2) == k
。您可以轻松显示等效性。
例如,案例4:
a)floor(2k+1/2)*(2l+1) + ( floor((2k+2)/2) - floor((2k+1)/2) ) * floor((2l+2)/2) = 2kl+k + (k+1 - k)*(l+1) = 2kl + k + l + 1
b)floor(((2k+1)*(2l+1)+1)/2) = floor((4kl+2k+2l+2)/2) = 2kl + k + l + 1
因此,这两个方程是等价的。
答案 2 :(得分:1)
有趣的是,这个问题说它是平等的,当你测试几个偶数和奇数值时它似乎就是这样。但这很容易枯燥的数学,所以没有人检查所有的情况。我也很懒,而且,即使我更像一个数学家,我还是使用一些复制粘贴进行了快速计算机检查:
bool diff = false;
int n = 100;
for(int w = -n; w<n; ++w){
for(int h = -n; h<n; ++h){
int a = (h/2)*w+ ( (h+1)/2-h/2 ) * (w+1)/2 ;
int b = (w * h + 1) / 2;
if (a!=b) diff = true;
}
}
cout << (diff ? "a != b" : "a == b") << endl;
我发现它不等于w = -1和h = -1,很容易检查a = 0和b = 1.这就是“简单的简化”经常引入新的bug。
PS:公平地说,我猜w和h是宽度和高度,所以它们可能总是正面的。但是没有指定(并且根据经验,其他一些代码可能会返回负宽度)答案 3 :(得分:0)
这是一个直接的数学问题。只需证明以下内容:
(h / 2)* w +((h + 1)/ 2-h / 2)*(w + 1)/ 2 =(w * h + 1)/ 2