将Int转换为Float会失去Swift中大数字的精度

XCode 6.3.1 Swift 1.2

let value: Int = 220904525 let intmax = Int.max let float = Float(value) // Here is an error probably let intFromFloat = Int(float) let double = Double(value) println("intmax=\(intmax) value=\(value) float=\(float) intFromFloat=\(intFromFloat) double=\(double)") // intmax=9223372036854775807 value=220904525 float=2.20905e+08 intFromFloat=220904528 double=220904525.0 

初始值是220904525.但是当我将它转换为浮动时它变为220904528.为什么?

这是由于浮点格式的工作方式。 Float是一个32位浮点数,以IEEE 754格式存储,基本上是科学记数法,有些位分配给该值,有些位分配给指数(在基数2中),如图所示-precision浮点数维基百科文章显示:

32位浮点格式

所以实际数字表示为

 (sign) * (value) * (2 ^ (exponent)) 

因为分配给实际存储整数值(24)的比特数小于在普通整数(全部32)中为此分配的比特数,所以为了给指数腾出空间,大数字的较低有效位数将被牺牲,以换取表示几乎无限数的能力(正常的Int只能表示-2 ^ 31到2 ^ 31-1范围内的整数)。

一些粗略的测试表明,直到167772162 ^ 24 )的每个整数都可以精确地表示在32位浮点数中,而较大的整数将四舍五入到最接近2的幂的倍数。

请注意,这不是Swift特有的。 这种浮点格式是几乎所有编程语言中使用的标准格式。 这是我使用普通C从LLDB获得的输出:

如果您需要更高的精度,请使用Double 。 双精度浮点数使用64位内存,具有更高的精度。

32位浮点数只能容纳约7-9个有效数字。 如果需要更多数字,精度将会丢失。

请参阅java中有多少有效数字具有浮点数和双精度数? 用于计算。

在Swift中,你可以使用Double ,它可以容纳更多数字(64位浮点数)或NSDecimalNumber ,它以十进制格式保存数字,并且不会丢失精度,因此它特别适合财务计算。 但是,性能要差得多。