Swift:从字符串创建双精度型会将 0000000000001 附加到结果数字
Swift: Creating a double from a String appends 0000000000001 to the resulting number
我正在尝试使用 Double(myTextField.text!)!
从 UITextField
中获取 Double
值。问题是,当我输入某些数字时,我会在数字末尾附加 0000000000001。例如,Double("9.05")!
给出值 9.050000000000001
而不是预期的 9.05
.
任何人都可以解释为什么会发生这种情况,以及我如何避免/修复它?
在此先感谢您的帮助。
作为 Eric D. 在评论中定义请检查 http://floating-point-gui.de/basic/
您可以格式化字符串以获得所需的输出:
var strVal = "9.05"
var dbl : Double = (NSString(format: "%.2f", (strVal as NSString).doubleValue)).doubleValue
println(dbl)
它在 Xcode 版本 6.3.2
中工作
试试这个
var value: Double = (swiftString as NSString).doubleValue
参见:
这是一个浮点数字二进制表示的普遍问题,其中 9.05 无法准确表示。
在操场上试试这个:
9.05 // 9.050000000000001
所以即使直接初始化值也不是"workaround"
正如一些人指出的那样,潜在的问题是当您以二进制形式存储 9.05 时,会出现舍入错误。所以它没有附加一些价值;它在四舍五入后向您显示正确的值(二进制)。这很像以十进制存储 2/3。您最终得到“6.66667”,这似乎是错误的,但由于四舍五入。 1/100 在二进制中是“0.00000010100011110101...”。
要得到你想要的,你需要格式化。 Ashish 给出了一个工作示例,但在 Swift 的最新版本中它变得更容易了。你不再需要 as NSString
:
import Foundation
let strVal = "9.05"
let doubleVal = Double(strVal)! // Convert String to Double
let formattedStr = String(format: "%.2f", doubleVal) // Double -> String w/ formatting
print(formattedStr)
您可能对 double 值与它如何表示为十进制数字之间的区别感到困惑。你不能用有限的二进制数字表示 9.05,就像你不能用有限的十进制数字表示 2/3 一样。总会有一些舍入误差。这就是为什么,例如,您不能安全地与 ==
两个浮点数进行比较。
如果你真正想要的是做十进制数学,那么你有两个选择:
- 以定点而不是浮点工作。将所有内容乘以 100 并将其存储为
Int
。对于许多问题,这是一个理想的解决方案。
NSDecimalNumber
。这在 Cocoa 中可用,让您可以用十进制而不是二进制进行数学运算。 9.05 作为 NSDecimalNumber
正好是 9.05。对于更一般的问题,这是一个很好的解决方案,但实施起来有点困难。
我正在尝试使用 Double(myTextField.text!)!
从 UITextField
中获取 Double
值。问题是,当我输入某些数字时,我会在数字末尾附加 0000000000001。例如,Double("9.05")!
给出值 9.050000000000001
而不是预期的 9.05
.
任何人都可以解释为什么会发生这种情况,以及我如何避免/修复它?
在此先感谢您的帮助。
作为 Eric D. 在评论中定义请检查 http://floating-point-gui.de/basic/
您可以格式化字符串以获得所需的输出:
var strVal = "9.05"
var dbl : Double = (NSString(format: "%.2f", (strVal as NSString).doubleValue)).doubleValue
println(dbl)
它在 Xcode 版本 6.3.2
中工作试试这个
var value: Double = (swiftString as NSString).doubleValue
参见:
这是一个浮点数字二进制表示的普遍问题,其中 9.05 无法准确表示。
在操场上试试这个:
9.05 // 9.050000000000001
所以即使直接初始化值也不是"workaround"
正如一些人指出的那样,潜在的问题是当您以二进制形式存储 9.05 时,会出现舍入错误。所以它没有附加一些价值;它在四舍五入后向您显示正确的值(二进制)。这很像以十进制存储 2/3。您最终得到“6.66667”,这似乎是错误的,但由于四舍五入。 1/100 在二进制中是“0.00000010100011110101...”。
要得到你想要的,你需要格式化。 Ashish 给出了一个工作示例,但在 Swift 的最新版本中它变得更容易了。你不再需要 as NSString
:
import Foundation
let strVal = "9.05"
let doubleVal = Double(strVal)! // Convert String to Double
let formattedStr = String(format: "%.2f", doubleVal) // Double -> String w/ formatting
print(formattedStr)
您可能对 double 值与它如何表示为十进制数字之间的区别感到困惑。你不能用有限的二进制数字表示 9.05,就像你不能用有限的十进制数字表示 2/3 一样。总会有一些舍入误差。这就是为什么,例如,您不能安全地与 ==
两个浮点数进行比较。
如果你真正想要的是做十进制数学,那么你有两个选择:
- 以定点而不是浮点工作。将所有内容乘以 100 并将其存储为
Int
。对于许多问题,这是一个理想的解决方案。 NSDecimalNumber
。这在 Cocoa 中可用,让您可以用十进制而不是二进制进行数学运算。 9.05 作为NSDecimalNumber
正好是 9.05。对于更一般的问题,这是一个很好的解决方案,但实施起来有点困难。