首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Enumerable.Average和OverflowException

Enumerable.Average和OverflowException
EN

Stack Overflow用户
提问于 2011-04-19 19:29:34
回答 1查看 640关注 0票数 11

也许是一个无用的问题:

代码语言:javascript
复制
public static double Average<TSource>(
    this IEnumerable<TSource> source,
    Func<TSource, int> selector
)

上述方法引发的异常之一也是OverflowException:序列中元素的和大于Int64.MaxValue。

我假设这个例外的原因是,平均值之和是使用S类型的变量long计算的吗?但是既然返回值是double类型的,为什么设计师不选择S也是double类型呢?

谢谢

EN

回答 1

Stack Overflow用户

发布于 2011-04-19 19:59:59

首先,我注意到,除非您已经超过了一个长的界限,否则不会出现异常。你要怎么做?每一个int最多可以是20亿,而一个长的顶部大约是80亿,所以这意味着你必须取超过40亿个int的平均值才能触发异常。这就是你经常要解决的问题吗?

假设是为了争论。做双倍的数学会失去精度,因为双算术被舍入到十五个小数点左右。观看:

代码语言:javascript
复制
using System;
using System.Collections.Generic;
static class Extensions
{
    public static double DoubleAverage(this IEnumerable<int> sequence)
    {
        double sum = 0.0;
        long count = 0;
        foreach(int item in sequence) 
        {
            ++count;
            sum += item;
        }
        return sum / count;
    }
    public static IEnumerable<T> Concat<T>(this IEnumerable<T> seq1, IEnumerable<T> seq2)
    {
        foreach(T item in seq1) yield return item;
        foreach(T item in seq2) yield return item;
    }
}


class P
{
    public static IEnumerable<int> Repeat(int x, long count)
    {
        for (long i = 0; i < count; ++i) yield return x;
    }

    public static void Main()
    {
        System.Console.WriteLine(Repeat(1000000000, 10000000).Concat(Repeat(1, 90000000)).DoubleAverage()); 
        System.Console.WriteLine(Repeat(1, 90000000).Concat(Repeat(1000000000, 10000000)).DoubleAverage()); 
    }
}

在这里,我们用双算术两个数列进行平均:一个是{10亿,10亿,10亿……千万次..。10亿,1,1.九千万次,和第一次和最后一次相同的顺序。如果运行代码,就会得到不同的结果。没有太大的不同,但是不同,而且随着序列的延长,差异会越来越大。长算术是精确的;对于每一次计算,可能都会出现双重运算,这意味着随着时间的推移,可能会产生巨大的错误。

完全在in上进行操作,导致浮点舍入错误的积累,这似乎是非常意外的。这是在浮点数上执行操作时所期望的事情,而不是在ints上执行时所期望的那样。

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5721603

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档