2015-08-15 69 views
0

我试图让使用下面的代码int数组的平均值:为什么我不能在Swift中减少内部整数?

let numbers = [1,2,3,4,5] 
let avg = numbers.reduce(0) { return $0 + $1/numbers.count } 
print(avg) // 1 

这显然是不正确。但是,如果我删除分工封闭外:

let numbers = [1,2,3,4,5] 
let avg = numbers.reduce(0) { return $0 + $1 }/numbers.count 
print(avg) // 3 

宾果!我想我还记得在某处读过的东西(不能回想起它是否与Swift,JavaScript或编程数学有关),这与将长度除以长度产生一个浮点/双倍的事实有关。 (1 + 2)/5 = 0.6这将在总和内舍入为0。不过,我期望((1 + 2) + 3)/5 = 1.2返回1,但它也似乎返回0

随着双打,计算按预期工作无论怎样它的计算,只要我箱的双数整数

let numbers = [1.0,2.0,3.0,4.0,5.0] 
let avg = numbers.reduce(0) { return $0 + $1/Double(numbers.count) } 
print(avg) // 3 

我想我明白了为什么(也许不是?)。但我不能拿出一个可靠的例子来证明这一点。

任何帮助和/或解释是非常赞赏。谢谢。

+0

int/int - > int':必须提升类型* first *做浮点除法。 – user2864740

回答

2

该部门不产生双重;你在做整数除法。

你没有得到((1 + 2) + 3 etc.)/5

在第一种情况下,您将获得(((((0 + (1/5 = 0)) + (2/5 = 0)) + (3/5 = 0)) + (4/5 = 0)) + (5/5 = 1)) = 0 + 0 + 0 + 0 + 0 + 1 = 1

在第二种情况下,您得到((((((0 + 1) + 2) + 3) + 4) + 5)/5) = 15/5 = 3

在第三种情况下,双精度损失比整数小得多,并且您得到类似(((((0 + (1/5.0 = 0.2)) + (2/5.0 = 0.4)) + (3/5.0 = 0.6)) + (4/5.0 = 0.8)) + (5/5.0 = 1.0))的东西。

+0

感谢您的输入。那么为什么当所有投入都是Ints时,2个减少案例会给出不同的结果? –

+0

@KyleGillen因为'int/int - > int'。精度损失发生在*每减少*。 – user2864740

+0

@KyleGillen,因为它们是不同的操作。 – muhmuhten

0

问题是,你正在试图用第一段代码没有数学意义。

序列的平均值是整个序列除以元素数量的总和。

reduce为正在调用的集合的每个成员调用lambda函数。因此,你正在总结和分开。

+1

该分区仅适用于$ 1(注意运算符优先级),并且累加器的初始值为零,数学很好。 – muhmuhten

+0

好吧,如果使用合理的算术,数学*将会很好。正如我们所看到的,事实并非如此。 – muhmuhten

+0

谢谢@ andre-artus。在我脑海中出现的某个点上,所以我假设:(1 + 2)/ 5 = 0.6>(0.6 + 3)/ 5 = 0.72等,这确实可以解释最高用例以1但是,在使用双打的情况下 - 为什么它按预期工作? –

相关问题