let dic : [Double : Double] = [1.1 : 2.3,2.3 : 1.1,1.2 : 2.3] print(dic)// [2.2999999999999998: 1.1000000000000001,1.2: 2.2999999999999998,1.1000000000000001: 2.2999999999999998] let double : Double = 2.3 let anotherdouble : Double = 1.1 print(double) // 2.3 print(anotherdouble) // 1.1
我不明白为什么编译器从字典中打印值不同?
我在Swift 3,Xcode 8.这是一个bug或一些奇怪的方法优化的东西或东西?
编辑
更奇怪的是:
有些价值观过去了,有的下降了,有些留下来吧! 1.1小于1.1000000000000001,而2.3是2.2999999999999998以上,1.2只是1.2
价值1.1正好. Swift使用(像许多其他语言)
二进制浮点数按照 IEEE 754
标准.
可以表示为Double的最接近的数字是1.1
1.100000000000000088817841970012523233890533447265625
最接近的数字可以表示为Double
2.29999999999999982236431605997495353221893310546875
打印该数字意味着它被转换为一个字符串
再次使用十进制表示法,并用不同的方法完成
精度,取决于打印数字的方式.
从HashedCollections.swift.gyb的源代码可以看出,描述方法
字典对于键和值都使用debugPrint()
而debugPrint(x)打印x.debugDescription的值
(如果x符合CustomDebugStringConvertible).
另一方面,如果x符合,print(x)将调用x.description
到CustomStringConvertible.
所以你看到的是不同的描述输出
和debug的描述:
print(1.1.description) // 1.1 print(1.1.debugDescription) // 1.1000000000000001
从Swift源代码可以看出
两者都使用swift_floatingPointToString()
功能在Stubs.cpp中,Debug参数分别设置为false和true.
此参数控制数字到字符串转换的精度:
int Precision = std::numeric_limits<T>::digits10; if (Debug) { Precision = std::numeric_limits<T>::max_digits10; }
有关这些常量的含义,请参见std::numeric_limits:
> digits10 – 可以表示没有变化的十进制数字数,
> max_digits10 – 区分此类型的所有值所需的十进制数字数.
因此,描述创建一个小数位数少的字符串.那字符串可以转换为双精度并返回一个字符串给出相同的结果.debugDescription创建一个具有更多十进制数字的字符串,这样就可以了任何两个不同的浮点值将产生不同的输出.