为什么我不能在 Swift 中的 reduce 中正确除整数?

Why can't I divide integers correctly within reduce in Swift?

我正在尝试使用以下代码获取整数数组的平均值:

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

这显然是不正确的。但是,如果我将除法器移除到闭包之外:

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

宾果!我想我记得在某个地方读过(不记得它是否与 Swift、JavaScript 或一般的编程数学有关)这与将总和除以长度这一事实有关产生一个浮点数/双精度数,例如(1 + 2) / 5 = 0.6 将在总和中向下舍入为 0。但是我希望 ((1 + 2) + 3) / 5 = 1.2 到 return 1,但是它似乎也是 return 0.

对于双精度数,无论采用哪种计算方式,计算都会按预期进行,只要我将计数整数框为双精度数即可:

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

我想我明白为什么(也许不明白?)。但是我想不出一个具体的例子来证明。

非常感谢任何帮助和/或解释。谢谢。

除法不产生双倍;你在做整数除法。

你没有得到 ((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))

问题是您尝试使用第一段代码在数学上没有意义。

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

reduce 为被调用的集合中的每个成员调用 lambda 函数。因此,您一直在求和和除法。

对于难以理解原始答案的人。

考虑一下。

let x = 4
let y = 3 

let answer = x/y

您希望答案是 Double,但不是,它是 Int。为了让您得到一个不是四舍五入的 Int 的答案。您必须明确地将值声明为 Double。见下文

let doubleAnswer = Double(x)/Double(y)

希望对您有所帮助。