Swift double to string

174,678

Solution 1

It is not casting, it is creating a string from a value with a format.

let a: Double = 1.5
let b: String = String(format: "%f", a)

print("b: \(b)") // b: 1.500000

With a different format:

let c: String = String(format: "%.1f", a)

print("c: \(c)") // c: 1.5

You can also omit the format property if no formatting is needed.

Solution 2

let double = 1.5 
let string = double.description

update Xcode 7.1 • Swift 2.1:

Now Double is also convertible to String so you can simply use it as you wish:

let double = 1.5
let doubleString = String(double)   // "1.5"

Swift 3 or later we can extend LosslessStringConvertible and make it generic

Xcode 11.3 • Swift 5.1 or later

extension LosslessStringConvertible { 
    var string: String { .init(self) } 
}

let double = 1.5 
let string = double.string  //  "1.5"

For a fixed number of fraction digits we can extend FloatingPoint protocol:

extension FloatingPoint where Self: CVarArg {
    func fixedFraction(digits: Int) -> String {
        .init(format: "%.*f", digits, self)
    }
}

If you need more control over your number format (minimum and maximum fraction digits and rounding mode) you can use NumberFormatter:

extension Formatter {
    static let number = NumberFormatter()
}

extension FloatingPoint {
    func fractionDigits(min: Int = 2, max: Int = 2, roundingMode: NumberFormatter.RoundingMode = .halfEven) -> String {
        Formatter.number.minimumFractionDigits = min
        Formatter.number.maximumFractionDigits = max
        Formatter.number.roundingMode = roundingMode
        Formatter.number.numberStyle = .decimal
        return Formatter.number.string(for: self) ?? ""
    }
}

2.12345.fractionDigits()                                    // "2.12"
2.12345.fractionDigits(min: 3, max: 3, roundingMode: .up)   // "2.124"

Solution 3

In addition to @Zaph's answer, you can create an extension on Double:

extension Double {
    func toString() -> String {
        return String(format: "%.1f",self)
    }
}

Usage:

var a:Double = 1.5
println("output: \(a.toString())")  // output: 1.5

Solution 4

Swift 3+: Try these line of code

let num: Double = 1.5

let str = String(format: "%.2f", num)

Solution 5

to make anything a string in swift except maybe enum values simply do what you do in the println() method

for example:

var stringOfDBL = "\(myDouble)"
Share:
174,678
tim_yng
Author by

tim_yng

Updated on July 18, 2022

Comments

  • tim_yng
    tim_yng almost 2 years

    Before I updated xCode 6, I had no problems casting a double to a string but now it gives me an error

    var a: Double = 1.5
    var b: String = String(a)
    

    It gives me the error message "double is not convertible to string". Is there any other way to do it?

  • zaph
    zaph almost 10 years
    @MaximShoustin The OP does not have enough rep to up vote and answer, 15 is required. I also disagree with creating an Extension, when the statement: a.toString() is seen by another developer there will definitely be a WTF moment.
  • Maxim Shoustin
    Maxim Shoustin almost 10 years
    @Zaph why not. For sure you can add some prefix and change it to myToString() to be sure that its custom definition. But like in other languages prototyping leads to avoiding code duplicate and good maintenance.
  • Alex Guerrero
    Alex Guerrero over 9 years
    @MaximShoustin newbie question: what's the difference between println("output: \(a.toString())") and println("output: \(a)"). Second option doesn't cause compile errors. Is this option a bad practice?
  • Esqarrouth
    Esqarrouth over 9 years
    is this a hack or is this a legit way to do it? would it cause any problems with different ios versions?
  • Leo Dabus
    Leo Dabus over 9 years
    No, you won't have any problems with different ios versions. It also works for OSX. BTW this is what you get when doing String Interpolation with a Double or an Int.
  • Nico
    Nico about 9 years
    What about a double with a bigger fraction digits number? Like let a = 2.34934340320 let stringValue = String(format: "%f", a) will give 2.349343
  • zaph
    zaph about 9 years
    The display can be controlled with the printf formatting options, see: String Format Specifiers and printf(3).
  • Patrik Vaberer
    Patrik Vaberer about 9 years
    Very useful. You can't format like %f. And It works also for Int so you have one way to do it for two types.
  • Megaetron
    Megaetron almost 9 years
    You just have to change your format to control the amount of digits: format:"%.1f" = 1 digit // 1.5; format:"%.5f" = 5 digits // 1.50000
  • Alexandre G.
    Alexandre G. about 8 years
    Please update your answer, in Swift 2.1 you just have to do String(yourDouble).
  • zaph
    zaph about 8 years
    The answer is about using format: to control the output display, note the second example output, note format:"%.1f". Updated print for 2.1.
  • Admin
    Admin about 8 years
    This won't work for 0.00001, it becomes "1e-05" as a string.
  • McSullivan
    McSullivan about 7 years
    This returns e.g. "Optional(6.1696108999999995)" for me.
  • Eric Aya
    Eric Aya over 6 years
    It's the same solution as the one given by @shiv-kumar stackoverflow.com/a/46487485/2227743
  • J A S K I E R
    J A S K I E R about 6 years
    You can use let instead of var. There is not need now to call it several times.
  • Kinergy
    Kinergy over 5 years
    Is there a clever way to write such an extension to Double or FloatingPoint that would work on an Optional Double to return an empty String?
  • Leo Dabus
    Leo Dabus almost 5 years
    why are you returning optional but assigning .nan if nil? You should do either one or another. Not both. Btw Whats wrong with using the String initializer ? You can also make it more generic extending LossLessStringConvertible protocol instead of extending Double extension LosslessStringConvertible { var string: String { return .init(self) } }
  • Giuseppe Mazzilli
    Giuseppe Mazzilli almost 5 years
    U are right returning Double? Is a refuse since I already check it is nil and return NaN
  • rmaddy
    rmaddy over 4 years
    Replace String(format: "%.\(digits)f", self as! CVarArg) with String(format: "%.*f", digits, self as! CVarArg)
  • rmaddy
    rmaddy over 4 years
    Replace String(format:"%."+numberOfDecimalPlaces.description+"f", number) with String(format:"%.*f", numberOfDecimalPlaces, number)
  • rmaddy
    rmaddy over 4 years
    Replace String(format: "%.\(points)f", self) with String(format: "%.*f", points, self)
  • Leo Dabus
    Leo Dabus over 3 years
    @Kinergy extension Optional where Wrapped: LosslessStringConvertible { var string: String { guard let unwrapped = self else { return "" } return .init(unwrapped) } }
  • flymg
    flymg over 2 years
    Yes, this is the absolute correct answer, and the only one which keeps pain with locals away.