Convert String to Float in Swift
Asked Answered
E

22

116

I'm trying to convert numbers taken from a UITextField, which I presume, are actually Strings, and convert them to Float, so I can multiply them.

I have two UITextfields which are declared as follows:

@IBOutlet var wage: UITextField
@IBOutlet var hour: UITextField

When the user presses a UIButton I want to calculate the wages the user earns, but I can't, as I need to convert them to floats first, before I can use them.

I know how to convert them to an integer by doing this:

var wageConversion:Int = 0
wageConversion = wage.text.toInt()!

However, I have no idea how to convert them to floats.

Elspet answered 6/6, 2014 at 15:35 Comment(0)
S
218

Swift 2.0+

Now with Swift 2.0 you can just use Float(Wage.text) which returns a Float? type. More clear than the below solution which just returns 0.

If you want a 0 value for an invalid Float for some reason you can use Float(Wage.text) ?? 0 which will return 0 if it is not a valid Float.


Old Solution

The best way to handle this is direct casting:

var WageConversion = (Wage.text as NSString).floatValue

I actually created an extension to better use this too:

extension String {
    var floatValue: Float {
        return (self as NSString).floatValue
    }
}

Now you can just call var WageConversion = Wage.text.floatValue and allow the extension to handle the bridge for you!

This is a good implementation since it can handle actual floats (input with .) and will also help prevent the user from copying text into your input field (12p.34, or even 12.12.41).

Obviously, if Apple does add a floatValue to Swift this will throw an exception, but it may be nice in the mean time. If they do add it later, then all you need to do to modify your code is remove the extension and everything will work seamlessly, since you will already be calling .floatValue!

Also, variables and constants should start with a lower case (including IBOutlets)

Sculpin answered 6/6, 2014 at 18:15 Comment(7)
The extension isn't required, the bridge is done automatically by Swift, as @tom states all you need is Wage.text.floatValue. Not sure whether this changed between the answer being posted and now, but it's been there for a while.Ragg
@GoodbyeStackOverflow, I am using Beta 4 and it definitely does not work. Maybe they changed it in Beta 5? NSString has floatValue extension but String does not. Get error: 'String' does not have member named floatValueSculpin
This might be the reason. Also, do you have import Foundation at the top of your file?Ragg
I don't consider this very safe, at least for Swift standards, since if the string is not a number, NSString.floatValue just returns 0. This should trigger an Exception or at least return nil.Symbolic
let floatValue = (Float)(Wage.text) ... In Swift 2.0Endopeptidase
For the float string of "12,3" in German, Float("12,3") = nil not work, ("12,3" as? NSString)?.floatValue = Optional(12.0) also not good.Heger
let a = Float32("45.6") will return the Float value from the string in Swift 4.2. Even we can also use Float64() method for the same.Cameliacamella
E
25

Because in some parts of the world, for example, a comma is used instead of a decimal. It is best to create a NSNumberFormatter to convert a string to float.

let numberFormatter = NSNumberFormatter()
numberFormatter.numberStyle = NSNumberFormatterStyle.DecimalStyle
let number = numberFormatter.numberFromString(self.stringByTrimmingCharactersInSet(Wage.text))
Eyla answered 27/6, 2014 at 18:20 Comment(0)
A
20

I convert String to Float in this way:

let numberFormatter = NSNumberFormatter()
let number = numberFormatter.numberFromString("15.5")
let numberFloatValue = number.floatValue

println("number is \(numberFloatValue)") // prints "number is 15.5"
Auriculate answered 16/8, 2014 at 11:50 Comment(1)
I think this is the best solution (at least for swift 4+), the main reason being that it returns an optional (as opposed to NSString.floatValue, which simply return 0 if something is wrong.). Note that NSNumberFormatter was changed NumberFormatter.Apogeotropism
R
9

Update

The accepted answer shows a more up to date way of doing

Swift 1

This is how Paul Hegarty has shown on Stanford's CS193p class in 2015:

wageConversion = NSNumberFormatter().numberFromString(wage.text!)!.floatValue

You can even create a computed property for not having to do that every time

var wageValue: Float {
        get {
            return NSNumberFormatter().numberFromString(wage.text!)!.floatValue
        }
        set {
            wage.text = "\(newValue)"
        }
    }
Rheotropism answered 5/2, 2015 at 22:8 Comment(0)
S
7

Below will give you an optional Float, stick a ! at the end if you know it to be a Float, or use if/let.

let wageConversion = Float(wage.text)
Selmore answered 28/1, 2016 at 15:38 Comment(0)
G
6

Using the accepted solution, I was finding that my "1.1" (when using the .floatValue conversion) would get converted to 1.10000002384186, which was not what I wanted. However, if I used the .doubleValue instead, I would get the 1.1 that I wanted.

So for example, instead of using the accepted solution, I used this instead:

var WageConversion = (Wage.text as NSString).doubleValue

In my case I did not need double-precision, but using the .floatValue was not giving me the proper result.

Just wanted to add this to the discussion in case someone else had been running into the same issue.

Getup answered 6/10, 2014 at 19:19 Comment(0)
A
4
extension String {    
    func floatValue() -> Float? {
        return Float(self)
    }
}
Agnosticism answered 26/3, 2016 at 7:38 Comment(1)
why not simply return Float(self) ?Richelieu
C
4

Here is a Swift 3 adaptation of Paul Hegarty's solution from rdprado's answer, with some checking for optionals added to it (returning 0.0 if any part of the process fails):

var wageFloat:Float = 0.0

if let wageText = wage.text {
    if let wageNumber = NumberFormatter().number(from: wageText) {
        wageFloat = wageNumber.floatValue
    }
}

By the way, I took Stanford's CS193p class using iTunes University when it was still teaching Objective-C.

I found Paul Hegarty to be a FANTASTIC instructor, and I would highly recommend the class to anyone starting out as an iOS developer in Swift!!!

Claim answered 7/1, 2017 at 21:25 Comment(1)
This is the only correct answer for Swift 3 or later. You must use a NumberFormatter to deal with user entered floating point numbers.Wohlert
L
3
import Foundation
"-23.67".floatValue // => -23.67

let s = "-23.67" as NSString
s.floatValue // => -23.67
Lissalissak answered 14/7, 2014 at 2:12 Comment(1)
Explain why this code works. This prevents copying and pasting without understanding of its operation.Rostov
A
3

In swift 4

let Totalname = "10.0" //Now it is in string

let floatVal  = (Totalname as NSString).floatValue //Now converted to float
Achitophel answered 14/3, 2019 at 11:41 Comment(0)
H
2

Double() builds an Double from an Int, like this:

var convertedDouble = Double(someInt)

Note that this will only work if your text actually contains a number. Since Wage is a text field, the user can enter whatever they want and this will trigger a runtime error when you go to unbox the Optional returned from toInt(). You should check that the conversion succeeded before forcing the unboxing.

if let wageInt = Wage.text?.toInt() {
    //we made it in the if so the conversion succeeded.
    var wageConversionDouble = Double(wageInt)
}

Edit:

If you're sure the text will be an integer, you can do something like this (note that text on UITextField is also Optional)):

if let wageText = Wage.text {
    var wageFloat = Double(wageText.toInt()!)
}
Holozoic answered 6/6, 2014 at 15:37 Comment(5)
Well, I am only allowing the user to enter in numbers as the keypad is a Decimal Pad, so they can't actually enter in anything other than numbers.Elspet
wageConversionFloat will never be the float, it crashes directly if the input string is a kind of float like 234.56. how could it be an accepted/upvoted solution...?Devito
This answer does not work if the text contains a decimal value. Example - this answer will return 3 if the text field has 3.5. This is because the text is first converted to an Int, then the Int is converted to a Float.Wohlert
@StephenFox Keep in mind that a user can paste non-numeric text into the text field or the user may have an external keyboard. Never rely on just the keyboard to ensure data entry.Wohlert
actually it does work, with whole numbers, just not decimals. a decimal will throw a fatal error!Mercurochrome
F
2
Works on Swift 5+

import Foundation

let myString:String = "50"
let temp = myString as NSString
let myFloat = temp.floatValue
print(myFloat)  //50.0
print(type(of: myFloat)) // Float

// Also you can guard your value in order to check what is happening whenever your app crashes.

guard let myFloat = temp.floatValue else {
fatalError(" fail to change string to float value.")
}
Franky answered 12/11, 2020 at 4:27 Comment(3)
Please add some explanations.Kantian
Tips for AnsweringLevelheaded
generally changing String directly to float value fails. so first we have to change it into NS string and then to float. this way xcode also becomes happy lol.Franky
T
2

I convert String to Float in this way:

let wage:Float = Float(textField.text!)!
Termless answered 12/3, 2021 at 2:31 Comment(0)
F
1

You have two options which are quite similar (by the approach and result):

// option 1:
var string_1 : String = "100"
var double_1 : Double = (string_1 as NSString).doubleValue + 99.0

// option 2: 
var string_2 : NSString = "100"
// or:  var string_2 = "100" as NSString
var number_2 : Double = string_2.doubleValue;
Foot answered 15/6, 2014 at 22:25 Comment(1)
bridgeToObjectiveC() was removed in Beta 5Bestiary
F
1

This is how I approached it. I did not want to "cross the bridge", as it has been removed from Xcode 6 beta 5 anyway, quick and dirty:

extension String {

    // converting a string to double
    func toDouble() -> Double? {

        // split the string into components
        var comps = self.componentsSeparatedByString(".")

        // we have nothing
        if comps.count == 0 {
            return nil
        }
        // if there is more than one decimal
        else if comps.count > 2 {
            return nil
        }
        else if comps[0] == "" || comps[1] == "" {
            return nil
        }

        // grab the whole portion
        var whole = 0.0
        // ensure we have a number for the whole
        if let w = comps[0].toInt() {
            whole = Double(w)
        }
        else {
            return nil
        }

        // we only got the whole
        if comps.count == 1 {

            return whole

        }

        // grab the fractional
        var fractional = 0.0
        // ensure we have a number for the fractional
        if let f = comps[1].toInt() {

            // use number of digits to get the power
            var toThePower = Double(countElements(comps[1]))

            // compute the fractional portion
            fractional = Double(f) / pow(10.0, toThePower)

        }
        else {
            return nil
        }

        // return the result
        return whole + fractional
    }

    // converting a string to float
    func toFloat() -> Float? {

        if let val = self.toDouble() {
            return Float(val)
        }
        else {
            return nil
        }

    }

}


// test it out
var str = "78.001"

if let val = str.toFloat() {
    println("Str in float: \(val)")
}
else {
    println("Unable to convert Str to float")
}

// now in double
if let val = str.toDouble() {
    println("Str in double: \(val)")
}
else {
    println("Unable to convert Str to double")
}
Futch answered 6/8, 2014 at 23:54 Comment(3)
Because in some parts of the world, for example, a comma is used instead of a decimal. It is best to create a NSNumberFormatter to convert a string to float. Look at @DmitriFuerle AnswerBestiary
@PartiallyFrozenOJ Have you tried toDouble() function with "10" string I mean if there is no decimal. It will crash anyway. Because in that case count will be 1 and you are not handling that. It will crash at else if comps[0] == "" || comps[1] == "" . Anyway you are so serious in conversion.Endopeptidase
@PartiallyFrozenOJ But if condition was same in 2014 too. Anyway No problem!Endopeptidase
N
1

For the sake of completeness this is a solution using an extension of UITextField which can also consider a different locale.

For Swift 3+

extension UITextField {
    func floatValue(locale : Locale = Locale.current) -> Float {
        let numberFormatter = NumberFormatter()
        numberFormatter.numberStyle = .decimal
        numberFormatter.locale = locale

        let nsNumber = numberFormatter.number(from: text!)
        return nsNumber == nil ? 0.0 : nsNumber!.floatValue
    }
}
Newfangled answered 20/3, 2018 at 17:6 Comment(1)
As a general solution this should probably return a Float? and not treat invalid values as 0.0. Let the caller do something like let val = field.floatValue ?? 0.0 if a given case should treat the bad result as zero.Wohlert
O
1

I found another way to take a input value of a UITextField and cast it to a float:

    var tempString:String?
    var myFloat:Float?

    @IBAction func ButtonWasClicked(_ sender: Any) {
       tempString = myUITextField.text
       myFloat = Float(tempString!)!
    }
Odelsting answered 29/9, 2018 at 23:43 Comment(0)
P
1

you can use,

let wg = Float(wage.text!)

If you want to round the float to 2 decimal places:

let wg = Float(String(format: "%.2f",wage.text!)
Paralyse answered 16/5, 2020 at 3:8 Comment(0)
C
1

to convert string to Float in Xcode 11 as previous methods need modification

func stringToFloat(value : String) -> Float {
    let numberFormatter = NumberFormatter()
    let number = numberFormatter.number(from: value)
    let numberFloatValue = number?.floatValue
    return numberFloatValue!
}
Ca answered 14/2, 2021 at 10:10 Comment(0)
S
0

Swift 4/5, use just Float(value).

let string_value : String = "123200"

let float_value : Float = Float(string_value)

print(float_value)

Answer: 123200

Stickney answered 3/9, 2019 at 6:21 Comment(0)
U
-1

Use this:

 // get the values from text boxes
    let a:Double = firstText.text.bridgeToObjectiveC().doubleValue
    let b:Double = secondText.text.bridgeToObjectiveC().doubleValue

//  we checking against 0.0, because above function return 0.0 if it gets failed to convert
    if (a != 0.0) && (b != 0.0) {
        var ans = a + b
        answerLabel.text = "Answer is \(ans)"
    } else {
        answerLabel.text = "Input values are not numberic"
    }
Upbringing answered 13/6, 2014 at 6:44 Comment(1)
bridgeToObjectiveC() was removed in Beta 5Bestiary
U
-4

Easy way:

// toInt returns optional that's why we used a:Int?
let a:Int? = firstText.text.toInt()
let b:Int? = secondText.text.toInt()

// check a and b before unwrapping using !
if a && b {
    var ans = a! + b!
    answerLabel.text = "Answer is \(ans)"
} else {
    answerLabel.text = "Input values are not numberic"
}

you can use same approach for other calculations, hope this help !!

Upbringing answered 12/6, 2014 at 11:54 Comment(1)
As great as this is, he was asking for floatBandaranaike

© 2022 - 2024 — McMap. All rights reserved.