向所有高手提问一个简单问题 求五千个随机整型数的平均值的最优算法,前提是不能用除号(/) 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 存到数据库里AVG一下 这个行不... 如果可以用分数表示结果的话,我想到一种解法:一切从简单开始,让我们计算5个数的平均数:A、B、C、D、E;如果以A为基数结果应该是A+[(A-B)+(A-c)+(A-D)+(A-E)]/5,注意这个除数是5,那么如果它不是5而是10或者100的话呢?可以不通过除法,仅仅移动小数点位数就得到结果,幸运的是5×2=10,而乘法是加法的重复而已!不知道这样的思路是否回答楼主的问题 呵呵,我自己改进我的算法,将所有数加起来,加两遍,除以10000就是结果,只不过除以10000根本不需要经过除法字符串操作就可以解决Done! 能不能把所有数加起来,然后把值转换为float型,然后乘以0.0002??? 天哪,考虑效率还用上数组?就是为了不用除法?本来已经加好了5000数,得到结果total.(只是cpu肯定最快的操作了)为了不除以5000 -- 还不是因为浮点运算嘛(正是cpu浮点运算性能所在) ---非要搞个数组处理,呵呵~~~ 南辕北辙,我看性能大大下降了!!!处理如下:1. 还是使用C语言的位运算。加5000数,没法再优化(CPU本来就都是加法运算,除法运算也是加出来的)。合并位运算的处理方法:左移时,a << n, 表示 a*(2^n)右移时,a >> n, 表示 a/(2^n); 2. 按39楼和位运算处理total结果,就能得到平均值了。 我不懂怎样算法最优,不过可以这样实现需求int sum=0; //和int div=0; //商 整数部分int re=0; //余float dot=0; //小数部分float answer; //结果for(int i=0;i<5000;i++){ integerI=rand(t); //随机函数不确定是不是这么用 , t是时间,用于生成比较好的伪随机数 sum+=integerI; while(sum>5000){ //也可以全加完,最后在循环,那样的话sum需要long型,比较次数节省很多,看空间、时间的折中需求 div++; sum-=5000; }}re=sum+sum;while(re>1000){ dot+=0.1; re-=1000;}while(re>100){ dot+=0.01; re-=100;}while(re>10){ dot+=0.001; re-=10;}while(re!=0){ dot+=0.0001; re--;}answer=dot+div; 计算机内部 好像只有加法吧.-a可以看成 +(-a)*a可以看成 +a+a+a...+a/a可以看成 -a-a-a-a-a;如果说不能用加. 那么计算机也是搞不定的.幸好是不能用除. 39楼的公式是错的,不好意思哈。下面这个能用。public class Main { public static void main(String[] args) { System.out.println(1.0 / 5000 / Integer.MIN_VALUE); System.out.println( Math.pow(2, -12) - Math.pow(2, -14) + Math.pow(2, -16) + Math.pow(2, -19) - Math.pow(2, -22) - Math.pow(2, -25) - Math.pow(2, -28) + Math.pow(2, -31) - Math.pow(2, -33) - Math.pow(2, -37) - Math.pow(2, -39) - Math.pow(2, -41) //+ Math.pow(2, -44) - Math.pow(2, -47) //+ Math.pow(2, -51) - 0.0002); long a = 2353434323323L; System.out.println(a); System.out.println(a / 5000); System.out.println(fiveThousandth(a)); } public static long fiveThousandth(long a) { return ((a >> 8) - (a >> 10) + (a >> 12) + (a >> 15) - (a >> 18) - (a >> 21) - (a >> 24) + (a >> 27) - (a >> 29) - (a >> 33) - (a >> 35) - (a >> 37)) >> 4; }} 内部类错误 查询数据库的问题,如何查询数据库服务器中已有的所有数据库名 Java与C++哪个更有发展前景? jad反编译catch块丢失?大家有这样的经历吗?怎么解决呢 求把字符串为UTF-8的转为GBK的代码 控件数组的问题 [JAVA] Linked Structures 问题! 我是在校大专生,向各位专家请教.先谢谢了 我没学过,实在是解决不了了。 空格的网络传输 jar包运行问题 Applet在浏览器上运行的自动安装问题
如果以A为基数结果应该是A+[(A-B)+(A-c)+(A-D)+(A-E)]/5,注意这个除数是5,那么如果它不是5而是10或者100的话呢?可以不通过除法,仅仅移动小数点位数就得到结果,幸运的是5×2=10,而乘法是加法的重复而已!不知道这样的思路是否回答楼主的问题
字符串操作就可以解决Done!
天哪,考虑效率还用上数组?就是为了不用除法?
本来已经加好了5000数,得到结果total.(只是cpu肯定最快的操作了)
为了不除以5000 -- 还不是因为浮点运算嘛(正是cpu浮点运算性能所在) ---
非要搞个数组处理,呵呵~~~ 南辕北辙,我看性能大大下降了!!!处理如下:
1. 还是使用C语言的位运算。加5000数,没法再优化(CPU本来就都是加法运算,除法运算也是加出来的)。
合并位运算的处理方法:
左移时,a << n, 表示 a*(2^n)
右移时,a >> n, 表示 a/(2^n); 2. 按39楼和位运算处理total结果,就能得到平均值了。
int div=0; //商 整数部分
int re=0; //余
float dot=0; //小数部分
float answer; //结果for(int i=0;i<5000;i++){
integerI=rand(t); //随机函数不确定是不是这么用 , t是时间,用于生成比较好的伪随机数
sum+=integerI;
while(sum>5000){ //也可以全加完,最后在循环,那样的话sum需要long型,比较次数节省很多,看空间、时间的折中需求
div++;
sum-=5000;
}
}
re=sum+sum;
while(re>1000){
dot+=0.1;
re-=1000;
}
while(re>100){
dot+=0.01;
re-=100;
}
while(re>10){
dot+=0.001;
re-=10;
}
while(re!=0){
dot+=0.0001;
re--;
}answer=dot+div;
-a可以看成 +(-a)
*a可以看成 +a+a+a...+a
/a可以看成 -a-a-a-a-a;
如果说不能用加. 那么计算机也是搞不定的.
幸好是不能用除.
System.out.println(1.0 / 5000 / Integer.MIN_VALUE);
System.out.println(
Math.pow(2, -12) - Math.pow(2, -14)
+ Math.pow(2, -16)
+ Math.pow(2, -19) - Math.pow(2, -22) - Math.pow(2, -25) - Math.pow(2, -28)
+ Math.pow(2, -31) - Math.pow(2, -33) - Math.pow(2, -37) - Math.pow(2, -39) - Math.pow(2, -41)
//+ Math.pow(2, -44) - Math.pow(2, -47)
//+ Math.pow(2, -51)
- 0.0002); long a = 2353434323323L;
System.out.println(a);
System.out.println(a / 5000);
System.out.println(fiveThousandth(a));
} public static long fiveThousandth(long a) {
return ((a >> 8) - (a >> 10) + (a >> 12) + (a >> 15)
- (a >> 18) - (a >> 21) - (a >> 24) + (a >> 27)
- (a >> 29) - (a >> 33) - (a >> 35) - (a >> 37)) >> 4;
}
}