Getting the decimal part of a double in Swift

前端 未结 9 1411
小鲜肉
小鲜肉 2020-11-28 12:37

I\'m trying to separate the decimal and integer parts of a double in swift. I\'ve tried a number of approaches but they all run into the same issue...

let x:         


        
相关标签:
9条回答
  • 2020-11-28 13:01

    It's impossible to create a solution that will work for all Doubles. And if the other answers ever worked, which I also believe is impossible, they don't anymore.

    let _5678 = 1234.5678.description.drop { $0 != "." } .description // ".5678"
    Double(_5678)  // 0.5678
    
    let _567 = 1234.567.description.drop { $0 != "." } .description // ".567"
    Double(_567) // 0.5669999999999999
    
    0 讨论(0)
  • 2020-11-28 13:03

    Same approach as Alessandro Ornano implemented as an instance property of FloatingPoint protocol:

    Xcode 11 • Swift 5.1

    import Foundation
    
    extension FloatingPoint {
        var whole: Self { modf(self).0 }
        var fraction: Self { modf(self).1 }
    }
    

    1.2.whole    // 1
    1.2.fraction // 0.2
    

    If you need the fraction digits and preserve its precision digits you would need to use Swift Decimal type and initialize it with a String:

    extension Decimal {
        func rounded(_ roundingMode: NSDecimalNumber.RoundingMode = .bankers) -> Decimal {
            var result = Decimal()
            var number = self
            NSDecimalRound(&result, &number, 0, roundingMode)
            return result
        }
        var whole: Decimal { self < 0 ? rounded(.up) : rounded(.down) }
        var fraction: Decimal { self - whole }
    }
    

    let decimal = Decimal(string: "1234.99999999")!  // 1234.99999999
    let fractional = decimal.fraction                // 0.99999999
    let whole = decimal.whole                        // 1234
    let sum = whole + fractional                     // 1234.99999999
    
    0 讨论(0)
  • 2020-11-28 13:03

    There’s a function in C’s math library, and many programming languages, Swift included, give you access to it. It’s called modf, and in Swift, it works like this

    // modf returns a 2-element tuple,

    // with the whole number part in the first element,

    // and the fraction part in the second element

    let splitPi = modf(3.141592)

    splitPi.0 // 3.0

    splitPi.1 // 0.141592

    You can create an extension like below,

    extension Double {
    
        func getWholeNumber() -> Double {
    
            return modf(self).0
    
        }
    
        func getFractionNumber() -> Double {
    
            return modf(self).1
    
        }
    
    }
    
    0 讨论(0)
  • 2020-11-28 13:04

    You can use truncatingRemainder and 1 as the divider.

    Returns the remainder of this value divided by the given value using truncating division.

    Apple doc

    Example:

    let myDouble1: Double = 12.25
    let myDouble2: Double = 12.5
    let myDouble3: Double = 12.75
    
    let remainder1 = myDouble1.truncatingRemainder(dividingBy: 1)
    let remainder2 = myDouble2.truncatingRemainder(dividingBy: 1)
    let remainder3 = myDouble3.truncatingRemainder(dividingBy: 1)
    
    remainder1 -> 0.25
    remainder2 -> 0.5
    remainder3 -> 0.75
    
    0 讨论(0)
  • 2020-11-28 13:04

    Use Float since it has less precision digits than Double

    let x:Double = 1234.5678
    let n1:Float = Float(x % 1)           // n1 = 0.5678
    
    0 讨论(0)
  • 2020-11-28 13:05

    Swift 5.1

    let x:Double = 1234.5678
    
    let decimalPart:Double = x.truncatingRemainder(dividingBy: 1)    //0.5678
    let integerPart:Double = x.rounded(.towardZero)                   //1234
    

    Both of these methods return Double value.

    if you want an integer number as integer part, you can just use

    Int(x)
    
    0 讨论(0)
提交回复
热议问题