16

This is a super basic question, but, I can't seem to find an answer in Swift.

Question:

How do I get the whole integer part and fractional part (to the left and right of the decimal point respectively) of a number in Swift 2 and Swift 3? For example, for the number 1234.56789 —

How do I get the integer part 1234.56789 ?

How do I get the fractional part 1234.56789 ?

rmaddy
  • 314,917
  • 42
  • 532
  • 579
user4806509
  • 2,925
  • 5
  • 37
  • 72

8 Answers8

48

You could do simple floor and truncating:

let value = 1234.56789
let double = floor(value) // 1234.0
let integer = Int(double) // 1234
let decimal = value.truncatingRemainder(dividingBy: 1) // 0.56789
Thomas
  • 2,003
  • 18
  • 30
14

No need for extensions. Swift already has built in function for this.

let aNumber = modf(3.12345)
aNumber.0 // 3.0
aNumber.1 // 0.12345
Just a coder
  • 15,480
  • 16
  • 85
  • 138
  • This answer would be way more useful if it referred to the Swift docs for modf. Unfortunately, there pretty much aren't any. The best Swift-specific docs I could find were [here](https://www.alphacodingskills.com/swift/notes/swift-math-modf.php), which claim it's in the Foundation library, but the Apple Xcode Developer docs place it in the Kernel math module. As far as I can tell, this is the same `modf` function found in [standard C](https://en.cppreference.com/w/c/numeric/math/modf). – brotskydotcom Oct 04 '21 at 23:00
  • Use aNumber.0.description.dropLast(2) if you don't want the point zero at the end. – Brian M Jul 24 '22 at 01:34
13

Swift 4.xm, 5.x complete solution: I credit @Thomas solution also I'd like to add few things which allow us to use separated parts in 2 string part. Especially when we want to use 2 different UILabel for main and decimal part of the number.

Separated integer and decimal label

Extension below is also managing number quantity of decimal part. I thought it might be useful.

UPDATE: Now, it is working perfectly with negative numbers as well!

public extension Double{
func integerPart()->String{
    let result = floor(abs(self)).description.dropLast(2).description
    let plusMinus = self < 0 ? "-" : ""
    return  plusMinus + result
}
func fractionalPart(_ withDecimalQty:Int = 2)->String{
    let valDecimal = self.truncatingRemainder(dividingBy: 1)
    let formatted = String(format: "%.\(withDecimalQty)f", valDecimal)
    let dropQuantity = self < 0 ? 3:2
    return formatted.dropFirst(dropQuantity).description
}
Trevor
  • 1,051
  • 12
  • 16
  • Thanks dude. This is the most powerful solution – Ali Ihsan URAL Dec 14 '18 at 08:37
  • To support negative numbers, replace the return in the fraction part with this: formatted.drop(while: {$0 != "."}).description – MetaImi Feb 29 '20 at 19:47
  • @MetaImi I've tried your proposition; it is confusing with positive numbers in my tests. Now I updated the code above for positive and negative numbers are working perfectly. Thank you for your interest. – Trevor Mar 05 '20 at 13:26
  • In the ```integerPart()``` you at first use the ```abs``` and then you decide if it is a negative number with ```plusMinus```. Why did you use the ```abs``` in the first place? – Starsky Aug 12 '20 at 14:08
  • I calculate String formatting there, floor needs (+) value, I did long time ago, probably didn't have right result otherwise try and propose a better line if it can work without ```abs``` – Trevor Aug 22 '20 at 15:32
5

Convert your number into String later separate string from .

Try this:-

let number:Float = 123.46789
let numberString = String(number)
let numberComponent = numberString.components(separatedBy :".")
let integerNumber = Int(numberComponent [0])
let fractionalNumber = Int(numberComponent [1])
Irshad Ahmad
  • 1,363
  • 11
  • 17
4

You could do this ->

let x:Double = 1234.5678
let y:Double = Double(Int(x))
let z:Double = x - Double(Int(x))
print("\(x) \(y) \(z)")

Where x is your original value. y is the integer part and z is the fractional part.

Edit

Thomas answer is the one you want ...

Anders Cedronius
  • 2,036
  • 1
  • 23
  • 29
2

modf() works bad with numbers > 1 billion

@Trevor behaves like modf()

@Andres Cedronius example behaves like modf() too (i tried modify it)

@Irshad Ahmed solution is nice

there is some convenience convertions

For some reason you need more control, check out https://developer.apple.com/documentation/foundation/numberformatter

extension Double {

    /// 1.00234 -> 1.0
    var integerPart: Double {
        return Double(Int(self))
    }

    /// 1.0012 --> 0.0012
    var fractionPart: Double {
        let fractionStr = "0.\(String(self).split(separator: ".")[1])"
        return Double(fractionStr)!
    }

    /// 1.0012 --> "0.0012"
    var fractionPartString: String {
        return "0.\(String(self).split(separator: ".")[1])"
    }

    /// 1.0012 --> 12
    var fractionPartInteger: Int {
        let fractionStr = "\(String(self).split(separator: ".")[1])"
        return Int(fractionStr)!
    }

}
print(1000.0.integerPart)  // 1000.0
print(1000.0.fractionPart) // 0.0
print(1000.1.integerPart)  // 1000.0
print(1000.2.fractionPart) // 0.2
print(1_000_000_000.1.integerPart) // 1000000000.0
print(100_000_000.13233.fractionPart) // 0.13233

Eugene
  • 129
  • 1
  • 5
2

This will definitely work for you in swift 5 and 4

let number = 3.145443
let integerValue = String(format: "%.0f", number)
let integerValue1 = String(format: "%.1f", number)
let integerValue2 = String(format: "%.2f", number)
print(integerValue)
print(integerValue1)
print(integerValue2)

//Output
3
3.1
3.14
Navdeep Paliwal
  • 349
  • 3
  • 7
0
var specimen0:Double = 1234.56789

var significant0 = Double.IntegerLiteralType(specimen0) // result is an integer
var fractionals0 = specimen0 - Double(significant0)


var specimen1:Float = -1234.56789

var significant1 = Float.IntegerLiteralType(specimen1) // result is an integer
var fractionals1 = specimen1 - Float(significant1)


var specimen2:CGFloat = -1234.56789

var significant2 = CGFloat.IntegerLiteralType(specimen2) // result is an integer
var fractionals2 = specimen2 - CGFloat(significant2)

These are all built in as of Swift 5.3, I am sure even earlier...

rezwits
  • 835
  • 7
  • 12
  • With Double (and Single), due to the way Floating numbers work, you're gonna end up with values for the fractional part, with things like: 0.567890000000034, and for single precision: 0.5678711 – rezwits Dec 31 '20 at 21:05