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