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,Xcode8。这是错误还是优化内容的怪异方法?
更奇怪的是:
有些价值观过去了,有些则跌破了,有些则保持不变!1.1小于1.1000000000000001,而2.3大于2.2999999999999998,1.2仅为1.2
如注释中已经提到的,a Double不能1.1精确存储值。Swift根据IEEE 754 标准使用(像许多其他语言一样)二进制浮点数。
Double
1.1
最接近的数目1.1可以被表示为Double是
1.100000000000000088817841970012523233890533447265625
与最接近的数目2.3可以被表示,作为一个Double是
2.3
2.29999999999999982236431605997495353221893310546875
打印 该数字表示将其再次转换为带有小数表示的字符串,并且以不同的精度完成此操作,具体取决于您如何打印该数字。
从源代码HashedCollections.swift.gyb一个可以看到description的方法 Dictionary使用debugPrint()两个键和值,和debugPrint(x)打印的值x.debugDescription (如果x符合CustomDebugStringConvertible)。
description
Dictionary
debugPrint()
debugPrint(x)
x.debugDescription
x
CustomDebugStringConvertible
另一方面,如果符合则print(x)呼叫。x.description``x``CustomStringConvertible
print(x)
x.description``x``CustomStringConvertible
所以,你看到的是输出不同description 和debugDescription的Double:
debugDescription
print(1.1.description) // 1.1 print(1.1.debugDescription) // 1.1000000000000001
从Swift源代码中,可以看到两者都使用Stubs.cpp中的swift_floatingPointToString() 函数,并且参数分别设置为和。此参数控制数字到字符串转换的精度:Debug``false``true
swift_floatingPointToString()
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
因此,description创建一个具有较少十进制数字的字符串。该字符串可以转换为a Double并返回给相同结果的字符串。 debugDescription创建具有更多十进制数字的字符串,以便任何两个不同的浮点值将产生不同的输出。