如何在Swift中将Double转换为Int?

84
我正试图弄清楚如何让我的程序在我不需要任何小数位时去除整数后的.0
@IBOutlet weak var numberOfPeopleTextField: UITextField!
@IBOutlet weak var amountOfTurkeyLabel: UILabel!
@IBOutlet weak var cookTimeLabel: UILabel!
@IBOutlet weak var thawTimeLabel: UILabel!

var turkeyPerPerson = 1.5
var hours: Int = 0
var minutes = 0.0

func multiply (#a: Double, b: Double) -> Double {
    return a * b
}

func divide (a: Double , b: Double) -> Double {
    return a / b
}

@IBAction func calculateButton(sender: AnyObject) {
    var numberOfPeople = numberOfPeopleTextField.text.toInt()
    var amountOfTurkey = multiply(a: 1.5, b: Double(numberOfPeople!))
    var x: Double = amountOfTurkey
    var b: String = String(format:"%.1f", x)
    amountOfTurkeyLabel.text = "Amount of Turkey: " + b + "lbs"
    
    var time = multiply(a: 15, b:  amountOfTurkey)
    var x2: Double = time
    var b2: String = String(format:"%.1f", x2)
    if (time >= 60) {
        time = time - 60
        hours = hours + 1
        minutes = time
        var hours2: String = String(hours)
        var minutes2: String = String(format: "%.1f", minutes)
        
        cookTimeLabel.text = "Cook Time: " + hours2 + " hours and " + minutes2 + " minutes"
    } else {
        cookTimeLabel.text = "Cook Time: " + b2 + "minutes"
    }
   
}

我需要写一个if语句来将Double转换为Int才能使这个程序工作吗?


请使用 toInt() 函数来将 DOUBLEVALUE 的名称转换为整数。 - Wolfgang Wilke
10个回答

160

您可以使用:

Int(yourDoubleValue)

这将把double转换为int。

或者当使用String格式时,使用0而不是1:

String(format: "%.0f", yourDoubleValue)

这将只显示您的Double值,没有小数位,而不将其转换为int。


49
这不是一个好的方法,如果超出Int的范围,它将会崩溃。例如: Int(Double.greatestFiniteMagnitude) - Tomáš Linhart
3
回应Tomas Linhart的观点,这种方法并不安全。例如:Int(Double.infinity) // 崩溃 - Scott Marchant

60

在将 Double 值转换之前最好先验证其大小,否则可能会导致崩溃。

extension Double {
    func toInt() -> Int? {
        if self >= Double(Int.min) && self < Double(Int.max) {
            return Int(self)
        } else {
            return nil
        }
    }
}

崩溃是容易演示的,只需使用 Int(Double.greatestFiniteMagnitude) 即可。


4
Int(exactly:) 无法将无法精确转换为整数的 Double 值成功转换为整数。例如,Int(exactly: 3.1) 将返回 nil - Isaac Overacker
1
@IsaacOveracker 您是正确的,那是错误的信息。我已经将其删除了。 - Tomáš Linhart
2
严格来说,>=<= 更加正确,不是吗? - BaseZen
@BaseZen 不可以。:-) 那会导致崩溃。 - Tomáš Linhart
1
@TomášLinhart 舍入崩溃只发生在正数方面,其中-1偏移量会引起问题。Double可以精确表示2^63或9223372036854775808(高一个)或9223372036854774784(低511个),但不在中间任何地方。然而,2^-63在两种表示法中都是准确的(毕竟都是二进制),并且>=确实有效。 - BaseZen
显示剩余3条评论

8

应该能够正常工作:

// round your double so that it will be exactly-convertible
if let converted = Int(exactly: double.rounded()) {
  doSomethingWithInteger(converted)
} else {
  // double wasn't convertible for a reason, it probably overflows
  reportAnError("\(double) is not convertible")
}

init(exactly:) 几乎与init(:)相同,唯一的区别是init(exactly:)在失败时不会崩溃,而init(:)可能会调用fatalError(:)

您可以在这里检查它们的实现


7

另一种方法:

extension Double {
    
    func toInt() -> Int? {
        let roundedValue = rounded(.toNearestOrEven)
        return Int(exactly: roundedValue)
    }
    
}

6
使用NSNumberFormatter可以更通用地抑制字符串表示中Double值的.0小数位,它还考虑了当前语言环境的数字格式。
let x : Double = 2.0
let doubleAsString = NumberFormatter.localizedString(from: (NSNumber(value: x), numberStyle: .decimal) 
// --> "2"

当前正确的方式:NumberFormatter.localizedString(from: NSNumber(value:self), number: .decimal) - Dmitry Senashenko

1
  1. 将double转换为NSNumber
  2. 对于Int64使用.int64Value变量,对于Int使用.intValue
  3. 我正在存储像时间戳这样的长整型值,因此使用Int64以获得更高的精度

注意:

从double转换为Int或Int(someDouble)可能会在范围超出情况下导致异常错误,因此使用Int64(someDouble)和Int(someDouble)都不合适,而NSNumber(floatLiteral:value_InDouble).intValue则不会出现任何此类错误。


  let value_Int64 = NSNumber(floatLiteral: value_InDouble).int64Value

OR

  let value_Int = NSNumber(floatLiteral: value_InDouble).intValue

1

Swift 4 - Xcode 9

let value = doubleToInteger(data:"ENTER DOUBLE VALUE")

func doubleToInteger(data:Double)-> Int {
    let doubleToString = "\(data)"
    let stringToInteger = (doubleToString as NSString).integerValue
            
    return stringToInteger
}

0
如果您不在意非常大的值,可以使用此代码将Doubl固定到最大/最小Int值。
let bigDouble   = Double.greatestFiniteMagnitude
let smallDouble = -bigDouble

extension Double {
    func toIntTruncated() -> Int {
        let maxTruncated  = min(self, Double(Int.max).nextDown) // Nota bene: crashes without `nextDown`
        let bothTruncated = max(maxTruncated, Double(Int.min))
        return Int(bothTruncated)
    }
}

let bigDoubleInt   = bigDouble.toIntTruncated()
let smalDoublelInt = smallDouble.toIntTruncated()


0
extension Double {
  var prettyWeight: String {
    Int(exactly: self) == nil ? "\(self)kg" : "\(Int(self))kg"
  }
}

测试结果

for i in stride(from: 0.5, to: 10, by: 0.5) {
  print("\(i): \(i.prettyWeight)")
}

0.5: 0.5kg
1.0: 1kg
1.5: 1.5kg
2.0: 2kg
2.5: 2.5kg
3.0: 3kg
3.5: 3.5kg
4.0: 4kg
4.5: 4.5kg
5.0: 5kg
5.5: 5.5kg
6.0: 6kg
6.5: 6.5kg
7.0: 7kg
7.5: 7.5kg
8.0: 8kg
8.5: 8.5kg
9.0: 9kg
9.5: 9.5kg

0

Swift 4 - Xcode 10

如果 double 值超出 int 范围(因此无法表示),请使用此代码以避免崩溃:

将此私有扩展添加到您的类中:

private extension Int {

    init?(doubleVal: Double) {
        guard (doubleVal <= Double(Int.max).nextDown) && (doubleVal >= Double(Int.min).nextUp) else {
        return nil
    }

    self.init(doubleVal)
}

在你的类中这样使用扩展:

func test() {

    let d = Double(123.564)
    guard let intVal = Int(doubleVal: d) else {
        print("cannot be converted")
    }

    print("converted: \(intVal)")
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接