以下是Xcode 7.3.1 playground中的一个简单代码:
var str = "8.7"
print(Double(str))
输出令人惊讶:
的 Optional(8.6999999999999993)
另外,Float(str)
给出:8.69999981
对这个家伙的任何想法或理由? 任何对此的引用都将不胜感激。
另外,我应该如何将“8.7”转换为8.7为Double(或Float)?
修改
在swift中:
(str as NSString).doubleValue返回8.7
现在,那是好的。但我的问题仍然没有得到完整答案。我们找到了另一种选择,但为什么我们不能依赖Double(“8.7”)。请更深入地了解这一点。
修改2
(“6.9”as NSString).doubleValue //打印6.9000000000000004
所以,问题又开始了。
答案 0 :(得分:12)
这里有两个不同的问题。首先 - 正如已经提到的那样
注释 - 二进制浮点数不能代表
数字8.7
正好。 Swift使用IEEE 754标准进行表示
单精度和双精度浮点数,如果指定
let x = 8.7
然后,最接近的可表示数字存储在x
中,即
8.699999999999999289457264239899814128875732421875
关于这一点的更多信息可以在优秀中找到 问与答Is floating point math broken?。
第二个问题是:为什么数字有时会打印为" 8.7" 有时候是" 8.6999999999999993"?
let str = "8.7"
print(Double(str)) // Optional(8.6999999999999993)
let x = 8.7
print(x) // 8.7
Double("8.7")
与8.7
不同吗?比一个更准确
另一个?
要回答这些问题,我们需要知道print()
的方式
功能有效:
CustomStringConvertible
,则print函数调用其description
属性并打印结果
到标准输出。CustomDebugStringConvertible
,
print函数调用是debugDescription
属性并打印
结果是标准输出。 Double
类型符合CustomStringConvertible
,因此
let x = 8.7
print(x) // 8.7
产生与
相同的输出let x = 8.7
print(x.description) // 8.7
但是
会发生什么let str = "8.7"
print(Double(str)) // Optional(8.6999999999999993)
Double(str)
是可选,而struct Optional
不
符合CustomStringConvertible
,但是
CustomDebugStringConvertible
。因此打印功能调用
debugDescription
的{{1}}属性,依次为Optional
调用基础debugDescription
的{{1}}。
因此 - 除了可选之外 - 数字输出是
与
Double
但是let x = 8.7
print(x.debugDescription) // 8.6999999999999993
和description
之间的区别是什么?
对于浮点值?从Swift源代码可以看出
这最终都叫debugDescription
Stubs.cpp中的函数,swift_floatingPointToString
参数分别设置为Debug
和false
。
这可以控制数字到字符串转换的精度:
true
有关这些常量的含义,请参阅http://en.cppreference.com/w/cpp/types/numeric_limits:
int Precision = std::numeric_limits<T>::digits10;
if (Debug) {
Precision = std::numeric_limits<T>::max_digits10;
}
- 无需更改即可表示的小数位数digits10
- 区分此类型所有值所需的小数位数。因此max_digits10
创建一个十进制数较少的字符串。那
string可以转换为description
并返回给字符串
同样的结果。
Double
创建一个包含更多十进制数字的字符串,以便这样做
任何两个不同的浮点值都会产生不同的输出。
摘要:
debugDescription
和description
方法
点类型使用不同的精度转换为a
串。因此,因此,在您的情况下,您可能想要打开可选项 在打印之前:</ p>
debugDescription
为了更好地控制,请使用let str = "8.7"
if let d = Double(str) {
print(d) // 8.7
}
或格式化
使用NSNumberFormatter
格式打印。
另一种选择可以是使用%.<precision>f
代替(NS)DecimalNumber
(例如,对于货币金额),请参阅例如Round Issue in swift
答案 1 :(得分:1)
我会用:
df.columns = [['one', 'one'], ['one', 'two']]
答案 2 :(得分:0)
您可以使用此代码可能很有用。
print(str.doubleValue)