也许是一个无用的问题:
public static double Average<TSource>(
this IEnumerable<TSource> source,
Func<TSource, int> selector
)上述方法引发的异常之一也是OverflowException:序列中元素的和大于Int64.MaxValue。
我假设这个例外的原因是,平均值之和是使用S类型的变量long计算的吗?但是既然返回值是double类型的,为什么设计师不选择S也是double类型呢?
谢谢
发布于 2011-04-19 19:59:59
首先,我注意到,除非您已经超过了一个长的界限,否则不会出现异常。你要怎么做?每一个int最多可以是20亿,而一个长的顶部大约是80亿,所以这意味着你必须取超过40亿个int的平均值才能触发异常。这就是你经常要解决的问题吗?
假设是为了争论。做双倍的数学会失去精度,因为双算术被舍入到十五个小数点左右。观看:
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上执行时所期望的那样。
https://stackoverflow.com/questions/5721603
复制相似问题