Swift - How to convert String to Double
Swift 4.2+ String to Double
You should use the new type initializers to convert between String and numeric types (Double, Float, Int). It'll return an Optional type (Double?) which will have the correct value or nil if the String was not a number.
Note: The NSString doubleValue property is not recommended because it returns 0 if the value cannot be converted (i.e.: bad user input).
let lessPrecisePI = Float("3.14")
let morePrecisePI = Double("3.1415926536")
let invalidNumber = Float("alphabet") // nil, not a valid number
Unwrap the values to use them using if/let
if let cost = Double(textField.text!) {
print("The user entered a value price of \(cost)")
} else {
print("Not a valid number: \(textField.text!)")
}
You can convert formatted numbers and currency using the NumberFormatter
class.
let formatter = NumberFormatter()
formatter.locale = Locale.current // USA: Locale(identifier: "en_US")
formatter.numberStyle = .decimal
let number = formatter.number(from: "9,999.99")
Currency formats
let usLocale = Locale(identifier: "en_US")
let frenchLocale = Locale(identifier: "fr_FR")
let germanLocale = Locale(identifier: "de_DE")
let englishUKLocale = Locale(identifier: "en_GB") // United Kingdom
formatter.numberStyle = .currency
formatter.locale = usLocale
let usCurrency = formatter.number(from: "$9,999.99")
formatter.locale = frenchLocale
let frenchCurrency = formatter.number(from: "9999,99€")
// Note: "9 999,99€" fails with grouping separator
// Note: "9999,99 €" fails with a space before the €
formatter.locale = germanLocale
let germanCurrency = formatter.number(from: "9999,99€")
// Note: "9.999,99€" fails with grouping separator
formatter.locale = englishUKLocale
let englishUKCurrency = formatter.number(from: "£9,999.99")
Read more on my blog post about converting String to Double types (and currency).
Unable to convert String to double Swift
Please try this:
extension String {
func toDouble() -> Double? {
return NumberFormatter().number(from: self)?.doubleValue
}
}
You can access like that:
var myString = "1.2"
var myDouble = myString.toDouble()
You can remove optional as below:
if let data:NSDictionary = snap.value as! NSDictionary, let lat = data.value(forKey: "lat"),let lng = data.value(forKey: "lng") {
//then use thes let long to convert in Double
let latValue = lat.toDouble()
let lngValue = lng.toDouble()
}
String Convert into double in swift 4.1
You like this to convert String
into Double
:
let getLongijson: String = "67.0011"
let getlatijson: String = "24.8607"
let jsonlong = Double(getLongijson)
let jsonlat = Double(getlatijson)
Converting String to Double/Float loses precision for large numbers in Swift 5
If you want to keep your floating precision you need to use Decimal type and make sure to use its string initializer:
let value = "0.0000335651599321165"
if let decimal = Decimal(string: value) {
print(decimal)
}
This will print:
0.0000335651599321165
edit/update:
When displaying your value to the user with a fixed number of fraction digits you can use Number Formatter and you can choose a rounding mode as well:
extension Formatter {
static let number = NumberFormatter()
}
extension Numeric {
func fractionDigits(min: Int = 6, max: Int = 6, 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) ?? ""
}
}
let value = "0.0000335651599321165"
if let decimal = Decimal(string: value) {
print(decimal.fractionDigits()) // "0.000034\n"
}
swift: issue in converting string to double
There are two different issues here. First – as already mentioned in
the comments – a binary floating point number cannot represent the
number 8.7
precisely. Swift uses the IEEE 754 standard for representing
single- and double-precision floating point numbers, and if you assign
let x = 8.7
then the closest representable number is stored in x
, and that is
8.699999999999999289457264239899814128875732421875
Much more information about this can be found in the excellent
Q&A Is floating point math broken?.
The second issue is: Why is the number sometimes printed as "8.7"
and sometimes as "8.6999999999999993"?
let str = "8.7"
print(Double(str)) // Optional(8.6999999999999993)
let x = 8.7
print(x) // 8.7
Is Double("8.7")
different from 8.7
? Is one more precise than
the other?
To answer these questions, we need to know how the print()
function works:
- If an argument conforms to
CustomStringConvertible
, the print function calls itsdescription
property and prints the result
to the standard output. - Otherwise, if an argument conforms to
CustomDebugStringConvertible
,
the print function calls isdebugDescription
property and prints
the result to the standard output. - Otherwise, some other mechanism is used. (Not imported here for our
purpose.)
The Double
type conforms to CustomStringConvertible
, therefore
let x = 8.7
print(x) // 8.7
produces the same output as
let x = 8.7
print(x.description) // 8.7
But what happens in
let str = "8.7"
print(Double(str)) // Optional(8.6999999999999993)
Double(str)
is an optional, and struct Optional
does not
conform to CustomStringConvertible
, but toCustomDebugStringConvertible
. Therefore the print function calls
the debugDescription
property of Optional
, which in turn
calls the debugDescription
of the underlying Double
.
Therefore – apart from being an optional – the number output is
the same as in
let x = 8.7
print(x.debugDescription) // 8.6999999999999993
But what is the difference between description
and debugDescription
for floating point values? From the Swift source code one can see
that both ultimately call the swift_floatingPointToString
function in Stubs.cpp, with the Debug
parameter set to false
and true
, respectively.
This controls the precision of the number to string conversion:
int Precision = std::numeric_limits::digits10;
if (Debug) {
Precision = std::numeric_limits::max_digits10;
}
For the meaning of those constants, see http://en.cppreference.com/w/cpp/types/numeric_limits:
digits10
– number of decimal digits that can be represented without change,max_digits10
– number of decimal digits necessary to differentiate all values of this type.
So description
creates a string with less decimal digits. That
string can be converted to a Double
and back to a string giving
the same result.debugDescription
creates a string with more decimal digits, so that
any two different floating point values will produce a different output.
Summary:
- Most decimal numbers cannot be represented exactly as a binary
floating point value. - The
description
anddebugDescription
methods of the floating
point types use a different precision for the conversion to a
string. As a consequence, - printing an optional floating point value uses a different precision for the conversion than printing a non-optional value.
Therefore in your case, you probably want to unwrap the optional
before printing it:
let str = "8.7"
if let d = Double(str) {
print(d) // 8.7
}
For better control, use NSNumberFormatter
or formatted
printing with the %.
format.
Another option can be to use (NS)DecimalNumber
instead of Double
(e.g. for currency amounts), see e.g. Round Issue in swift.
String to Double conversion nil in different region Swift
Careful handling of localized numeric strings
let inputString = "12,8"
let formatter = NumberFormatter()
formatter.locale = Locale.current // Locale(identifier: "de")
let number = formatter.number(from: inputString)
print(number) // 12.8
Converting String to Double not working for bigger values in Swift
You can use number-formatter by setting their style as a currency type. I have implemented an example as follows:-
let formatter = NumberFormatter()
let frenchFormat = Locale(identifier: "fr_FR")
let germanFormat = Locale(identifier: "de_DE")
formatter.numberStyle = .currency
formatter.locale = frenchFormat
if let frenchPriceValue = formatter.number(from: "100,96€"){
print(frenchPriceValue) //Output is:- 100.96
}
OR
formatter.locale = germanFormat
if let germanPriceValue = formatter.number(from: "123,33€"){
print(germanPriceValue)//Output is:- 123.33
}
Fail to convert string to double Swift
When you are getting value form dictionary using subscript then they return value either in
String?
(if you declaredlet dict = [String: String]
)
or
Any?
(if you declaredlet dict = [String: Any]
orlet dict = ["key1" : "value1", "key2" : 2.0]
)
So you need to fist convert it from any to string.
if let stringValue = dict["amount"] as? String {
let dblValue = Double(stringValue) ?? 0.0
}
EDIT:
Explanation
See above image I have added 3 conditions. I hope everything is clear now.
Related Topics
Allow Only Numbers For Uitextfield Input
How to Upload Images to a Server in iOS With Swift
Command Failed Due to Signal: Segmentation Fault: 11
Swift - How to Get the File Path Inside a Folder
Issue Detecting Button Cellforrowat
Uinavigationbar Custom Back Button Without Title
How to Detect If App Is Being Built For Device or Simulator in Swift
Enabling Auto Layout in iOS 6 While Remaining Backwards Compatible With iOS 5
How Does View Controller Containment Work in iOS 5
Are There APIs For Custom Vibrations in Ios
Why Nsdateformatter Is Returning Null for a 19/10/2014 in a Brazilian Time Zone
Layout Issues After Updating to Xcode 8
How to Make Outlet Connection to a Constraint in Ib
How to Turn Page Programmatically in Uipageviewcontroller
Disable Gesture to Pull Down Form/Page Sheet Modal Presentation