How to use String(format: "%.2f")

Hello!

I'm learning Swift and as expected I'm stuck in an error.

error: no exact matches in call to initializer
print(String(format: "Readjustment: %.2f", readjustment))

Code:

if let salaryString = readLine(),
    let salary = Double(salaryString) {
    
        var percent: Double
        
        if salary <= 400.00 {
            percent = 15.0
        } else if salary <= 800.00 {
            percent = 12.0
        } else if salary <= 1200.00 {
            percent = 10.0
        } else if salary <= 2000.00 {
            percent = 7.0
        } else {
            percent = 4.0
        }
        
        let readjustment: Double = salary * (percent / 100.0)
        let newSalary: Double = salary + readjustment
        
        print(String(format: "Readjustment: %.2f", readjustment))
        print(String(format: "New salary: %.2f", newSalary))
}

What am I doing wrong?

1 Like

You're missing an import Foundation.

If you consult the reference docs for that initializer, you'll see that it's defined in Foundation (on NSString, which bridges to String).

4 Likes

Does a simpler version compile?

let readjustment = 1.0
print(String(format: "Readjustment: %.2f", readjustment))

It should and if it doesn't something is wrong in your other code (e.g. there's some rogue extension that messes things up).

If the simple version compiles - you may start with the original version that doesn't compile and step by step reduce it to the simplified version, checking after each step if the problem is still there – once the problem disappears you'd found the culprit.

That said, you might rather want to Output using string interpolation, which doesnβ€˜t require Foundation.

By the way, how do you control formatting (e.g. %.2f) with string interpolation?

2 Likes

Also consider this another newer string formatting mechanism in Foundation:

import Foundation

let readjustment = 1234.56789
let a = readjustment.formatted(.number.precision(.fractionLength(2)))
print(a) // 1,234.57
let locale = Locale(identifier: "ff_Adlm_GN")
let b = readjustment.formatted(.number.precision(.fractionLength(2)).locale(locale))
print(b) // πž₯‘⹁πž₯’πž₯“πž₯”.πž₯•πž₯—
5 Likes

Thank you! :+1:

Good to know. Thank you!

Or this that will do correct decimal number based on currency:

let v = 1234.56789
v.formatted(.currency(code: "ESP").presentation(.narrow)) // ₧1,235
v.formatted(.currency(code: "USD").presentation(.narrow)) // $1,234.57
v.formatted(.currency(code: "KWD").presentation(.narrow)) // KWD 1,234.568
v.formatted(.currency(code: "UYW").presentation(.narrow)) // UYW 1,234.5679

I don't know if it's possible to suppress the currency symbol should you need that.

I’ll just echo a comment I made on another similar post:

4 Likes

This helped me a lot! Sorry to be answering you only now.

Thank you, Alexander!

1 Like