【问题标题】:Checking if a double value is an integer - Swift检查双精度值是否为整数 - Swift
【发布时间】:2015-04-11 10:24:01
【问题描述】:

我需要检查一个双重定义的变量是否可以转换为 Int 而不会丢失其值。这不起作用,因为它们属于不同类型:

if self.value == Int(self.value)

self.value 是双精度数。

【问题讨论】:

    标签: swift int double


    【解决方案1】:
    extension FloatingPoint {
        var isWholeNumber: Bool { isNormal ? self == rounded() : isZero }
    }
    
    let double = 3.0    
    double.isWholeNumber        // true
    print(3.15.isWholeNumber)   // false
    

    【讨论】:

    • 请注意,如果 double 太大而无法转换为 Int,这将在运行时崩溃,请尝试 println(3.1e+100.isInteger)
    • 请在您的回答中添加解释
    【解决方案2】:

    现在有一个 Int(exactly:) 初始化程序可以直接告诉您这一点,而不会出现整数超出范围的问题。

    if Int(exactly: self) != nil { ... }
    

    如果结果实际上可以准确地存储在 Int 中,这只会返回一个非零值。有许多 Double 值是“整数”,但不适合 Int。 (请参阅 MartinR 对已接受答案的评论。)

    【讨论】:

      【解决方案3】:

      使用@ColinE 答案,我构建了一个扩展来处理 Double 无法转换为 Int 的情况以及另一个返回 Int 的函数:

      extension Double {
      
          func isInt() -> Bool {
              guard Double(Int.min) <= self && self <= Double(Int.max) else {
                  return false
              }
      
              return floor(self) == self
          }
      
          func toInt() -> Int? {
              guard Double(Int.min) <= self && self <= Double(Int.max) else {
                  return nil
              }
      
              return Int(self)
          }
      }
      

      我希望这对某人有所帮助,

      哈维

      【讨论】:

        【解决方案4】:

        小心。

        truncatingRemainder(dividingBy:) 可能很棘手。见下文:

        斯威夫特 4:

        //case 1
        let reminder = (4.1 * 100).truncatingRemainder(dividingBy: 1.0)
        
        //case 2
        let reminder2 = (410).truncatingRemainder(dividingBy: 1.0)
        
        // reminder = 0.9999999999999432
        // reminder2 = 0 
        

        【讨论】:

          【解决方案5】:

          快捷方式:

          let cals = [2.5, 2.0]
          
          let r = cals.map{ return Int(exactly: $0) == nil ?  "\($0)" : "\(Int($0))" }
          
          r // ["2.5", "2"]
          

          【讨论】:

            【解决方案6】:

            简单的解决方案

            我建议将值转换为Int,然后再转换为Double 并检查新值

            if value == Double(Int(value)) {
            // The value doesn't have decimal part. ex: 6.0
            
            } else {
            //  The value has decimal part. ex: 6.3
            
            }
            

            【讨论】:

              【解决方案7】:

              一个小扩展来检查这个:

              extension FloatingPoint {
                  var isInt: Bool {
                      return floor(self) == self
                  }
              }
              

              那就做吧

              let anInt = 1.isInt
              let nonInt = 3.142.isInt
              

              【讨论】:

                【解决方案8】:

                检查% 1 是否为零:

                斯威夫特 3:

                let dbl = 2.0
                let isInteger = dbl.truncatingRemainder(dividingBy: 1) == 0
                

                斯威夫特 2:

                let dbl = 2.0
                let isInteger = dbl % 1 == 0
                

                【讨论】:

                • 如果你能添加更多信息就好了,% 1 做了什么。我认为这将有助于更多的人理解代码。
                • 他正在使用所谓的模运算符:en.wikipedia.org/wiki/Modulo_operation
                【解决方案9】:

                如何将 Double 转换为 Int(将截断小数),然后再转换回 Double,然后将其与原始 Double 进行比较?例如:

                var dbl:Double = 22/3
                dbl == Double(Int(dbl))
                // false: dbl = 7.33333... Double(Int(dbl)) = 7.0
                
                dbl = 25
                dbl == Double(Int(dbl))
                // true: dbl = 25.0, Double(Int(dbl)) = 25.0
                

                【讨论】:

                  【解决方案10】:

                  使用 mod (%) 将不再起作用。

                  您现在可以使用:

                  let dbl = 2.0
                  let isInteger = dbl.truncatingRemainder(dividingBy: 1.0) == 0.0
                  

                  【讨论】:

                    【解决方案11】:

                    斯威夫特 3

                    if dbl.truncatingRemainder(dividingBy: 1) == 0 {
                      //it's an integer
                    }
                    

                    【讨论】:

                      【解决方案12】:

                      尝试对 double 值进行 'flooring',然后检查它是否未更改:

                      let dbl = 2.0
                      let isInteger = floor(dbl) == dbl // true
                      

                      如果不是整数则失败

                      let dbl = 2.4
                      let isInteger = floor(dbl) == dbl // false
                      

                      【讨论】:

                      • 这并不能完全解决问题“...如果双定义变量可转换为 Int 而不会丢失其值。”。例如,它为 3.1e100 提供 true,但该值无法转换为 Int,因为它太大了。
                      • 这是天才。
                      猜你喜欢
                      • 2011-11-09
                      • 2015-07-30
                      • 2020-12-23
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      相关资源
                      最近更新 更多