C/C++;整数运算
我偶然发现C/C++;整数运算,c,c++,math,C,C++,Math,我偶然发现 int a = (h/2)*w+ ( (h+1)/2-h/2 ) * (w+1)/2 ; 等于 int b = (w * h + 1) / 2 ; 当w和h是正整数时(假设没有溢出) 你能告诉我为什么这两个是一样的吗 编辑:整数->正整数。为了简化表达式,你必须考虑四种情况: h偶数和w偶数 h偶数和w奇数 h奇数和w偶数 h奇数和w奇数 从这里开始,应用适当的整数截断规则,您应该能够简化为第二个表达式。实际上这是一个数学问题:(整数)/2应该解释为floor。因此
int a = (h/2)*w+ ( (h+1)/2-h/2 ) * (w+1)/2 ;
等于
int b = (w * h + 1) / 2 ;
当w和h是正整数时(假设没有溢出)
你能告诉我为什么这两个是一样的吗
<>编辑:整数->正整数。
为了简化表达式,你必须考虑四种情况:
- h偶数和w偶数
- h偶数和w奇数
- h奇数和w偶数
- h奇数和w奇数
从这里开始,应用适当的整数截断规则,您应该能够简化为第二个表达式。实际上这是一个数学问题:(整数)/2应该解释为floor。因此,问题是: 显示
楼层(h/2)*w+(楼层((h+1)/2)-楼层(h/2))*楼层((w+1)/2)
等同于楼层((w*h+1)/2)
证明:
floor((2k+1)/2)==k
。您可以轻松地显示等价性
例如,案例4:
a) 楼层(2k+1/2)*(2l+1)+(楼层((2k+2)/2)-楼层((2k+1)/2))*楼层((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+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;
bool diff=false;
int n=100;
对于(int w=-n;w,这是一个直接的数学问题。只需证明以下内容:
(h/2)*w+((h+1)/2-h/2)*(w+1)/2=(w*h+1)/2一般来说还是具体值?你是怎么偶然发现的?一般来说。这不是家庭作业。我是在解决算法问题并将我的解决方案与另一个解决方案进行比较时发现的。这真的是太复杂了。格雷格的答案简单明了得多。这不是我的错;数学只是太复杂了:)我只展示了四个病例中的一个DIt有点复杂,但感谢您的详细阐述。如果您在考虑地板材料之前先进行计算,会更简单。你的表达式是`(h/2)*w+((h+1)/2-h/2)*(w+1)/2=(hw+(w+1)(h+1-h))/2=(hw+w+1)/2。如果你认为< /代码> 1/2是0,它进一步简化为<代码> W(H+ 1)/2 < /代码>,然后你可以像Minjang所说的那样继续分析。劳拉,不,你错了。你不能简单地像这样考虑方程:floor
和ceil
操作符不遵守/,*中的分布规律。很容易犯这样的错误。+1表示切片和骰子,更简单。感谢您的测试。是的,我错过了w和h为阳性的条件。实际上,我是在这种测试之后发布的。