Swift – 如何将string转换为Double
我试图用迅捷的语言写一个BMI程序。 而我得到这个问题:如何将string转换为双?
在Objective-C中,我可以这样做:
double myDouble = [myString doubleValue];
但是我怎样才能在Swift语言中实现这一点?
Swift 2+string加倍
您应该使用新的types初始值设定项在string和数字types(Double,Float,Int)之间进行转换。 它将返回一个可选types(Double?),如果该string不是数字,则该types将具有正确的值或nil。
注意:不build议使用NSString的doubleValue属性,因为如果该值无法转换(即:不良用户input),则返回0。
使用Swift 2+方法
let lessPrecisePI = Float("3.14") let morePrecisePI = Double("3.1415926536") let invalidNumber = Float("alphabet") // nil, not a valid number
打开这些值,使用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!)") }
在我的博客文章阅读更多关于转换string为双重types 。
Swift 2 Update有一些新的failable初始化函数可以让你以更通俗和安全的方式来做这件事(很多回答都指出,NSString的double值并不是非常安全,因为对于非数字值它返回0,这意味着doubleValue
为"foo"
和"0"
是相同的。)
let myDouble = Double(myString)
这会返回一个可选项,所以在传入double参数返回0的情况下,failable初始化函数会返回nil
。 您可以使用guard
, if-let
或map
来处理Optional<Double>
原文:您不需要像接受的答案提议那样使用NSString构造函数。 你可以像这样简单地桥接它:
(swiftString as NSString).doubleValue
对于更多的Swift感觉,使用NSFormatter()
避免了对NSString
,并且当string不包含Double
值(例如“test”不会返回0.0
)时返回nil
。
let double = NSNumberFormatter().numberFromString(myString)?.doubleValue
或者,扩展Swift的String
types:
extension String { func toDouble() -> Double? { return NSNumberFormatter().numberFromString(self)?.doubleValue } }
并使用它像toInt()
:
var myString = "4.2" var myDouble = myString.toDouble()
这将返回一个可选的Double?
必须打开。
要么强行解包:
println("The value is \(myDouble!)") // prints: The value is 4.2
或者用一个if let语句:
if let myDouble = myDouble { println("The value is \(myDouble)") // prints: The value is 4.2 }
更新:对于本地化,将语言环境应用于NSFormatter非常简单,如下所示:
let formatter = NSNumberFormatter() formatter.locale = NSLocale(localeIdentifier: "fr_FR") let double = formatter.numberFromString("100,25")
最后,如果您正在使用string包含货币符号的货币,则可以在格式化程序上使用NSNumberFormatterCurrencyStyle
。
另一个select是将其转换为NSString
并使用它:
let string = NSString(string: mySwiftString) string.doubleValue
这里有一个扩展方法,可以让你简单地调用一个Swiftstring的doubleValue()并获得一个双重返回(首先是示例输出)
println("543.29".doubleValue()) println("543".doubleValue()) println(".29".doubleValue()) println("0.29".doubleValue()) println("-543.29".doubleValue()) println("-543".doubleValue()) println("-.29".doubleValue()) println("-0.29".doubleValue()) //prints 543.29 543.0 0.29 0.29 -543.29 -543.0 -0.29 -0.29
这是扩展方法:
extension String { func doubleValue() -> Double { let minusAscii: UInt8 = 45 let dotAscii: UInt8 = 46 let zeroAscii: UInt8 = 48 var res = 0.0 let ascii = self.utf8 var whole = [Double]() var current = ascii.startIndex let negative = current != ascii.endIndex && ascii[current] == minusAscii if (negative) { current = current.successor() } while current != ascii.endIndex && ascii[current] != dotAscii { whole.append(Double(ascii[current] - zeroAscii)) current = current.successor() } //whole number var factor: Double = 1 for var i = countElements(whole) - 1; i >= 0; i-- { res += Double(whole[i]) * factor factor *= 10 } //mantissa if current != ascii.endIndex { factor = 0.1 current = current.successor() while current != ascii.endIndex { res += Double(ascii[current] - zeroAscii) * factor factor *= 0.1 current = current.successor() } } if (negative) { res *= -1; } return res } }
没有错误检查,但你可以添加它,如果你需要它。
从Swift 1.1开始,您可以直接将String
传递给const char *
参数。
import Foundation let str = "123.4567" let num = atof(str) // -> 123.4567 atof("123.4567fubar") // -> 123.4567
如果你不喜欢弃用的atof
:
strtod("765.4321", nil) // -> 765.4321
一个警告:转换的行为不同于NSString.doubleValue
。
atof
和strtod
接受0x
前缀hexstring:
atof("0xffp-2") // -> 63.75 atof("12.3456e+2") // -> 1,234.56 atof("nan") // -> (not a number) atof("inf") // -> (+infinity)
如果您更喜欢.doubleValue
行为,我们仍然可以使用CFString
桥接:
let str = "0xff" atof(str) // -> 255.0 strtod(str, nil) // -> 255.0 CFStringGetDoubleValue(str) // -> 0.0 (str as NSString).doubleValue // -> 0.0
尝试这个:
var myDouble = myString.bridgeToObjectiveC().doubleValue println(myDouble)
注意
在Beta 5中删除。这不再有效?
在Swift 2.0中,最好的方法是避免像Objective-C开发人员那样思考。 所以你不应该“将string转换为双精度”,而应该“从string初始化双精度值”。 苹果文档在这里: https : //developer.apple.com/library/ios//documentation/Swift/Reference/Swift_Double_Structure/index.html#//apple_ref/swift/structctr/Double/s : FSdcFMSdFSSGSqSd_
这是一个可选的init,因此您可以使用nil合并运算符(??)来设置默认值。 例:
let myDouble = Double("1.1") ?? 0.0
这是build立在@Ryu的答案上
只要你在一个使用点作为分隔符的国家,他的解决scheme就非常棒。 默认情况下, NSNumberFormatter
使用设备区域设置。 因此,如果数字使用点作为分隔符(通常是这种情况),那么在所有使用逗号作为默认分隔符的国家(包括法国作为@PeterK。)都会失败。 将此NSNumberFormatter的语言环境设置为US,并使用点作为分隔符replace该行
return NSNumberFormatter().numberFromString(self)?.doubleValue
同
let numberFormatter = NSNumberFormatter() numberFormatter.locale = NSLocale(localeIdentifier: "en_US_POSIX") return numberFormatter.numberFromString(self)?.doubleValue
因此完整的代码变成了
extension String { func toDouble() -> Double? { let numberFormatter = NSNumberFormatter() numberFormatter.locale = NSLocale(localeIdentifier: "en_US_POSIX") return numberFormatter.numberFromString(self)?.doubleValue } }
要使用这个,只需调用"Your text goes here".toDouble()
这将返回一个可选的Double?
正如@Ryu提到的,你可以强制展开:
println("The value is \(myDouble!)") // prints: The value is 4.2
或者使用if let
语句:
if let myDouble = myDouble { println("The value is \(myDouble)") // prints: The value is 4.2 }
在SWIFT 3上 ,您可以使用:
if let myDouble = NumberFormatter().number(from: yourString)?.doubleValue { print("My double: \(myDouble)") }
注意: – 如果一个string包含除数字或区域适当的组或小数点分隔符以外的任何字符,parsing将失败。 – string中的任何前导或尾随空格分隔符都将被忽略。 例如,string“5”,“5”和“5”都产生数字5。
采取从文档: https : //developer.apple.com/reference/foundation/numberformatter/1408845-号码
请在操场上检查一下!
let sString = "236.86" var dNumber = NSNumberFormatter().numberFromString(sString) var nDouble = dNumber! var eNumber = Double(nDouble) * 3.7
顺便在我的Xcode
.toDouble() – 不存在
.doubleValue从非数字string创build值0.0 …
正如已经指出的那样,实现这一目标的最好方法是直接铸造:
(myString as NSString).doubleValue
从此构build,你可以做一个本地Swiftstring扩展:
extension String { var doubleValue: Double { return (self as NSString).doubleValue } }
这可以让你直接使用:
myString.doubleValue
哪个会为你演出。 如果苹果不向本地string添加一个doubleValue
,只需要移除扩展名,剩下的代码就会自动编译好!
1。
let strswift = "12" let double = (strswift as NSString).doubleValue
2。
var strswift= "10.6" var double : Double = NSString(string: strswift).doubleValue
可能是这个帮助你。
带有可选区域的扩展
Swift 2.2
extension String { func toDouble(locale: NSLocale? = nil) -> Double? { let formatter = NSNumberFormatter() if let locale = locale { formatter.locale = locale } return formatter.numberFromString(self)?.doubleValue } }
Swift 3.1
extension String { func toDouble(_ locale: Locale) -> Double { let formatter = NumberFormatter() formatter.numberStyle = .decimal formatter.locale = locale formatter.usesGroupingSeparator = true if let result = formatter.number(from: self)?.doubleValue { return result } else { return 0 } } }
SWIFT 3
要清除,现在有一个默认的方法:
Double
类的public init?(_ text: String)
。
它可以用于所有类。
let c = Double("-1.0")
let f = Double("0x1c.6")
let i = Double("inf")
等
我还没有看到我正在寻找的答案。 我只是张贴在这里我的情况下,可以帮助任何人。 只有在您不需要特定格式时,此答案才有效。
Swift 3
extension String { var toDouble: Double { return Double(self) ?? 0.0 } }
或者你可以这样做:
var myDouble = Double((mySwiftString.text as NSString).doubleValue)
你可以使用StringEx 。 它通过string到数字的转换扩展了String
,包括toDouble()
。
extension String { func toDouble() -> Double? }
它validationstring,如果不能转换为double,则会失败。
例:
import StringEx let str = "123.45678" if let num = str.toDouble() { println("Number: \(num)") } else { println("Invalid string") }
还有什么作用:
// Init default Double variable var scanned: Double() let scanner = NSScanner(string: "String to Scan") scanner.scanDouble(&scanned) // scanned has now the scanned value if something was found.
在Swift 2.0中使用这个代码
let strWithFloat = "78.65" let floatFromString = Double(strWithFloat)
var stringValue = "55" var convertToDouble = Double((stringValue as NSString).doubleValue)
我发现更多的可读性来添加一个string扩展如下:
extension String { var doubleValue: Double { return (self as NSString).doubleValue } }
然后你可以写你的代码:
myDouble = myString.doubleValue
我的问题是逗号,所以我解决这个问题:
extension String { var doubleValue: Double { return Double((self.replacingOccurrences(of: ",", with: ".") as NSString).doubleValue) } }
我们可以使用由myString.doubleValue获取的CDouble值