【问题标题】:Why can't I divide integers in swift?为什么我不能快速除整数?
【发布时间】:2014-08-02 13:58:46
【问题描述】:

Swift "Tour" documentation 中,有一个练习,您可以在以下函数的基础上对一组数字进行平均:

func sumOf(numbers: Int...) -> Int {
    var sum = 0
    for number in numbers {
        sum += number
    }
    return sum
}

我可以使用以下方法来完成这项工作:

func averageOf(numbers: Double...) -> Double {
    var sum: Double = 0, countOfNumbers: Double = 0
    for number in numbers {
        sum += number
        countOfNumbers++
    }
    var result: Double = sum / countOfNumbers
    return result
}

我的问题是,为什么我必须将所有内容都转换为 Double 才能使其工作?如果我尝试使用整数,如下所示:

func averageOf(numbers: Int...) -> Double {
    var sum = 0, countOfNumbers = 0
    for number in numbers {
        sum += number
        countOfNumbers++
    }
    var result: Double = sum / countOfNumbers
    return result
}

我收到以下错误:Could not find an overload for '/' that accepts the supplied arguments

【问题讨论】:

  • var result: Double = Double(sum) / Double(countOfNumbers),或者你可以重载操作符,如果你愿意的话。
  • 您期待什么结果?整数截断平均转换为双精度数,还是将整数作为双精度数的平均值? (即 [4,3] 应该返回 3.5 (7.0/2) 还是 3 (7/2)?)
  • 请注意,如果您将两个Int 类型相除,任何余数都将被丢弃(整数除法)developer.apple.com/documentation/swift/int/2884531

标签: swift


【解决方案1】:

OP 似乎知道 代码的外观,但他明确询问 为什么 它不能以其他方式工作。

因此,“显式”是他正在寻找的答案的一部分:Apple 在“基础知识”->“整数和浮点转换”一章中的“语言指南”中写道:

整数和浮点数值类型之间的转换必须是 明确的

【讨论】:

  • 是的,谢谢,这正是我所追求的。直观地说,我希望如果我将结果(变量 返回值)转换为 Double,我已经告诉编译器该做什么。我还没有深入阅读语言指南,所以我不知道。
  • 我可能在这里遗漏了一些非常明显的东西,但我发现有趣的是,当除数和除数相等时,Swift 中的除法归结为正确的结果 (1.0)。
【解决方案2】:

你只需要这样做:

func averageOf(numbers: Int...) -> Double {
    var sum = 0, countOfNumbers = 0
    for number in numbers {
        sum += number
        countOfNumbers++
    }
    var result: Double = Double(sum) / Double(countOfNumbers)
    return result
}

【讨论】:

  • 变量“结果”从未发生变异;考虑更改为“让”常量。 ?
【解决方案3】:

您将/ 的输出分配给Double 类型的变量,因此Swift 认为您要调用此函数:

func /(lhs: Double, rhs: Double) -> Double

但是你传递给它的参数不是Doubles 并且 Swift 不做隐式转换。

【讨论】:

  • 谢谢,这也有帮助,我没有意识到“/”实际上只是一个常规函数。
  • 这对我来说是一个真正的啊哈,可能是最好的答案。 / 是一个接受 2 个参数的函数,这两个参数都必须是双精度数。它解释了在进行除法之前需要强制转换,并解释了 xcode 产生的错误消息。
【解决方案4】:

这可能会有所帮助:

func averageOf(numbers: Int...) -> Double {
    var sum = 0, countOfNumbers = 0
    for number in numbers {
        sum += number
        countOfNumbers++
    }
    var result: Double = Double(sum) / Double(countOfNumbers)
    return result
}

重载/ 运算符也是一种解决方案,就像在 Swift 4.x 中那样:

infix operator /: MultiplicationPrecedence
public func /<T: FixedWidthInteger>(lhs: T, rhs: T) -> Double {
    return Double(lhs) / Double(rhs)
}

【讨论】:

  • 在 swift 5 中获取此错误消息:二进制运算符 '/' 不能应用于两个 'Double?'操作数
  • 在应用任何操作数之前,您需要先解开 Double 值。
【解决方案5】:

我认为强制师没有必要。普通除法运算符虽然有效。 在下面的代码中,

func average(numbers:Int...)->Float{
    var sum = 0
    for number in numbers{
        sum += number
    }
    var average: Float = 0
    average = (Float (sum) / Float(numbers.count))
    return average
}
let averageResult = average(20,10,30)
averageResult

这里,两个浮点值被划分,当然是在类型转换之后,因为我将结果存储在浮点变量中并返回相同的值。

注意:我没有使用额外的变量来计算参数的数量。 “数字”被视为数组,因为 Swift 中的函数将可变数量的参数放入数组中。 “numbers.count”(类似于Objective C)将返回正在传递的参数的计数。

【讨论】:

    【解决方案6】:

    试试这个,但请注意 swift 不喜欢除以初始化为零或可能为零的整数,因此您必须使用 &/ 强制除法。这段代码有点冗长,但很容易理解,它给出了整数而不是浮点数或双精度的正确答案

    func sumOf(numbers: Int...) -> Int {
    var sum = 0
    var i = 0
    var avg = 1
    for number in numbers {
        sum += number
        i += 1
    }
    avg = sum &/ i
    return avg
    }
    sumOf()
    sumOf(42, 597, 12)
    

    【讨论】:

      【解决方案7】:

      当您可以直接获取参数时,没有理由手动跟踪参数的数量。

      func sumOf(numbers: Int...) -> Int {
          var sum = 0
          for number in numbers {
              sum += number
          }
          let average = sum &/ numbers.count
          return average
      }
      
      sumOf()
      sumOf(42, 597, 12)
      

      【讨论】:

        【解决方案8】:

        派对迟到了,但原因是在 Swift 中划分两个 INT 时,结果总是一个 INT。

        编译器通过截断小数点后的值来实现这一点(即 5 / 2 = 2;实际结果应该是 2.5)。

        要获得真正的平均值(非截断值),您需要转换为 Double,以便保留小数点后的值。否则会丢失。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-04-22
          • 2022-11-12
          • 1970-01-01
          • 2016-06-27
          • 1970-01-01
          相关资源
          最近更新 更多