我需要仅使用int作为数据类型来查找两个数字的平均值。我不能使用公式(x1 + x2)/ 2 = mean,因为如果数字足够大,会导致溢出。
我找到了这个公式
int mid = low + ((high - low) / 2);
来自此帖子Explanation of the safe average of two numbers。
但是,当涉及负数时,此公式不起作用。有没有人对如何解决这个问题有任何想法?感谢
编辑 - Java
答案 0 :(得分:3)
你说你不能使用μ=(x+y)/2
形式,但这基本上是计算这个有意义的唯一方法。你确实提出了一个关于溢出的好点,但所需要的只是一些非常基本的代数来找到它。还记得分配财产吗?
μ = (x + y) / 2 = x/2 + y/2
通过在添加它们之前将两个整数除以2,可以降低溢出的风险。尝试将两个值设置为Integer.MAX_VALUE
(尽管首先阅读整个帖子)。所以......
int avg(int x, int y) {
return x/2 + y/2;
}
......应该为你做。请记住,您是专门使用int
的?当涉及奇数整数时,你会有一些精确的问题需要担心...例如,如果你做avg(1, 1)
,你将得到0的结果。我将留下会计并修复那个小问题问题,但这应该让你走上正确的道路。
答案 1 :(得分:1)
这应该适用于负值和正值,因为在这种情况下符号的位不会移位:
// Convert the add operation as long to prevent overflow in case you use big
// integers
long total = (long) low + (long) high;
// Convert the mid value back to an int
int mid = (int) (total >> 1);
注意:当且仅当low
和high
都是int
时才会有效。根据您的问题,此处似乎就是这种情况。
答案 2 :(得分:0)
这样的事情应该有效
private int findAverage(int lower, int higher) {
int lowerCopy = lower;
int higherCopy = higher;
boolean averageFound = false;
while (!averageFound) {
lowerCopy++;
higherCopy--;
averageFound = isAverageFound(lowerCopy, higherCopy);
}
return getAverage(lowerCopy, higherCopy);
}
其中isAverageFound将通过检查值是彼此相等还是彼此相等来实现。
这适用于所有数字范围,正面或负面
答案 3 :(得分:-1)
private void findAverage(int lower, int higher) {
int lowerCopy = lower;
int higherCopy = higher;
int cnt = 1;
boolean averageFound = false;
while (!averageFound) {
lowerCopy++;
higherCopy--;
++cnt;
averageFound = isAverageFound(lowerCopy, higherCopy);
}
}
private boolean isAverageFound(int l, int h){
if(l < h)
return false;
else if(l == h){
System.out.print("average:" + l);
return true;
}else{
System.out.print("average:" + (h/2));
return true;
}
}
是。它还有待改变。对于大的负面和大正面范围,它将起作用。但是,我同意它需要O(高+低)时间。