为什么我不能在 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)
希望对您有所帮助。
我正在尝试使用以下代码获取整数数组的平均值:
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)
希望对您有所帮助。