怎么求十亿个64位整数的平均数?

ybxuwei 2015-03-30 10:29:43
加精
由于c语言能表示的最大长度的数是64位的,所以如果全部相加的,可能会溢出。除了写个大数运算的的方法外,还有没有其他更好的计算平均数的方法?
...全文
9505 173 打赏 收藏 转发到动态 举报
写回复
用AI写文章
173 条回复
切换为时间正序
请发表友善的回复…
发表回复
tincarl2 2015-10-10
  • 打赏
  • 举报
回复
刚刚学习C++,进来学习一下
baidu_31902807 2015-10-10
  • 打赏
  • 举报
回复
引用 31 楼 Liuyang378747340 的回复:
小学知识结合初一知识来得算法 1、找出十亿数据中的中值(小学数学里面的;例如:1,5,3,8,4,中值为4) 2、所有数减去这个中值(所得值应该是很小的,有正有负,这个中值相当于平常0) 4、把减得的值相加,再除以数据数量 5、所得的平均值再加上中值即可。
你先考虑下 得到中值这个过程的循环消耗在想那些吧..十亿个64位整数 等你得出中值浪费的性能则么都够用了 你这不是优化....是劣化吧. 数值少的时候可以这样..
二班的码农 2015-07-31
  • 打赏
  • 举报
回复
可以用数组保存数据,仿照数字相加的进位运算
Ingram--MSN 2015-07-31
  • 打赏
  • 举报
回复
看了看没看懂!
sdoqiulei 2015-07-31
  • 打赏
  • 举报
回复
[quote=引用 5 楼 zhao4zhong1 的回复:] 设前N个数的平均值已经算出为A(n),第n+1个数为D(n+1),则前N+1个数的平均值A(n+1)为: A(n+1)=(A(n)*n+D(n+1))/(n+1)[/quote 括号里面两个数相加也有可能溢出啊
li_rui_1220 2015-07-31
  • 打赏
  • 举报
回复
引用 2 楼 henry3695 的回复:
算法 把这些数依次相加,当快要溢出的时候记录 元素个数n 总数ndata 求出平均只 ndata/n 剩下的数据依次这么处理, 接着就是把平均值,再算平均值 ,到了最后就是平均值
这样算出的结果似乎不是整体的平均数吧,这类似滑动平均了吧
NotSimpleEasy 2015-06-30
  • 打赏
  • 举报
回复
我是来凑热闹的~
lm_whales 2015-06-29
  • 打赏
  • 举报
回复
注意,求商和余数的方法,如果每个数都在 2^64 -1附近有可能余数相加有溢出
lm_whales 2015-06-29
  • 打赏
  • 举报
回复
还有一种般办法是二倍精度法 用两个64 位的 unsigned,当作128 位数,进行运算 这样可以保证加法不溢出 ,最后做个除法即可 假设共有 2^63个数,每个数不超过 2^63 2^63*2^63 =2^126 <2^128 所有数加起来不会溢出,然后直接相除 和 = 连加 (a0:a(n-1)) 平均值 = 和( 两杯精度)/ 个数(一倍精度);
lm_whales 2015-06-29
  • 打赏
  • 举报
回复
求商和余数,叠加之,要保证余数相加不溢出即可
sher12 2015-06-03
  • 打赏
  • 举报
回复

    long long int n = 3;
    long long int arr[3] = {-2,1,3};
    long long int totle = 0;
    long long int mod = 0;
    for(int i = 0; i < n; i++)
    {
        long long int a = arr[i];
        totle += a / n;//totle不会超过64位
        mod += a % n;//mod在[-20亿,+20亿]之间,也不会超过64位
        totle += mod / n;
        mod %= n;
    }
    printf("%f\n", ((double)mod)/n + totle);
707wk 2015-05-03
  • 打赏
  • 举报
回复
先按块把数都分成有相同个数的块,然后分别计算每个块的平均值,重复上述步骤,直到只有一个数据块
ybxuwei 2015-05-03
  • 打赏
  • 举报
回复
没想到会有这么多回复,还没来得及全部看完。这个问题我已经有了方案,只有一次乘除运算,误差不大,速度也可以保证,这是针对无符号数的运算,要算有符号数,只需要修改一下数据类型和溢出判断逻辑。
#ifndef _SUMER_H_
#define _SUMER_H_

#include <stdint.h>
#include <math.h>

#define MAXUINT64 ((uint64_t)0xFFFFFFFFFFFFFFFF)

class sumer
{
public:
    sumer(): high_(0), low_(0), count_(0){}
    void add(uint64_t n)
    {   
        uint64_t sum = n + low_;
        if(sum < n && sum < low_)
        {   
            // overflow
            ++high_;
        }   
        low_ = sum;
        ++count_;
    }   
    uint64_t avg()
    {   
        double sqrtc = sqrt(count_);
        return (high_/sqrtc)*(MAXUINT64/sqrtc)+(low_/count_);
    }   
    uint64_t count(){return count_; }
    void clear() { high_ = low_ = count_ = 0; }
private:
    uint64_t high_;
    uint64_t low_;
    uint64_t count_;
};

#endif
7zkeeper 2015-04-22
  • 打赏
  • 举报
回复
基本的思路是分治法,十亿个数的存放问题是如何解决的? 计算模式就是分割数据,中间结果的保存,到最后的汇总中间结果,是典型的mapreduce模式,如果是常规的串行计算,那么要时间的成本是否可行是看需求
7zkeeper 2015-04-22
  • 打赏
  • 举报
回复
利用spark基本不需要做太多的事情 .....
liangbch 2015-04-22
  • 打赏
  • 举报
回复
引用 165 楼 tianfang 的回复:
[quote=引用 164 楼 liangbch 的回复:] 91楼的代码依然不是最简洁的,将带符号数转为无符号数,更简洁一点。下面的代码在91楼的基本框下进行了重写,将2^63进制改为2^64进制 这个不算简化,题目中没有说是有符号还是无符号。而无符号比有符号简单一点,所以我只写了有符号的
现在csdner有一种不好的倾向,大家都在表现自己,而从不学习别人的思路和代码。91楼的作者也不例外,165楼的回复说明,tianfang完全没有读懂我的代码。164楼的代码是在91楼的基础上改写的,功能完全相同,都是实现带符号64bit数的平均数,只是实现不同,代码更简洁。 by the way, 我在2000年就注册csdn帐号的,至今将近15年,几乎与csdn同龄,见证了csdn的创立,兴起和衰落。曾经的过去,大牛很多,帖子质量很高。但现在,我就不想说什么了... 看看14年前的这个帖子,有谁可以用四行代码求出1000000的阶乘
PandasRan 2015-04-22
  • 打赏
  • 举报
回复
31楼要在这么大量的数据中找中值,开销太大了
WizardOz 2015-04-22
  • 打赏
  • 举报
回复
什么业务需要这么精确的一个平均数?依我说随便抽几个样本算一下算了。
tianfang 2015-04-22
  • 打赏
  • 举报
回复
[quote=引用 164 楼 liangbch 的回复:] 91楼的代码依然不是最简洁的,将带符号数转为无符号数,更简洁一点。下面的代码在91楼的基本框下进行了重写,将2^63进制改为2^64进制 这个不算简化,题目中没有说是有符号还是无符号。而无符号比有符号简单一点,所以我只写了有符号的
reader1 2015-04-22
  • 打赏
  • 举报
回复
两个数相加,右移一位,然后每次加,右移一位。...... 或者八个数相加,右移四位。都是平均值。 程序好像不用很长。
加载更多回复(153)

64,660

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧