在 Swift 中将 Int 转换为 Float 会丢失大数的精度 [英] Converting Int to Float loses precision for large numbers in Swift

查看:53
本文介绍了在 Swift 中将 Int 转换为 Float 会丢失大数的精度的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

XCode 6.3.1 斯威夫特 1.2

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.但是当我将它转换为float时,它变成了220904528.为什么?

The initial value is 220904525. But when I convert it to float it becomes 220904528. Why?

推荐答案

这是由于浮点格式的工作方式.Float 是一个 32 位浮点数,以 IEEE 754 格式存储,这基本上是科学记数法,一些位分配给值,一些位分配给指数(以 2 为底),如下图来自 单精度浮点数维基百科文章显示:

This is due to the way the floating-point format works. A Float is a 32-bit floating-point number, stored in the IEEE 754 format, which is basically scientific notation, with some bits allocated to the value, and some to the exponent (in base 2), as this diagram from the single-precision floating-point number Wikipedia article shows:

所以实际数字表示为

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

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

Because the number of bits allocated to actually storing an integer value (24) is smaller than the number of bits allocated for this in a normal integer (all 32), in order to make room for the exponent, the less significant digits of large numbers will be sacrificed, in exchange for the ability to represent almost infinite numbers (a normal Int can only represent integers in the range -2^31 to 2^31 - 1).

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

Some rough testing indicates that every integer up to and including 16777216 (2 ^ 24) can be represented exactly in a 32-bit float, while larger integers will be rounded to the nearest multiple of some power of 2.

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

Note that this isn't specific to Swift. This floating-point format is a standard format used in almost every programming language. Here's the output I get from LLDB with plain C:

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

If you need higher precision, use a Double. Double precision floats use 64 bits of memory, and have higher precision.

这篇关于在 Swift 中将 Int 转换为 Float 会丢失大数的精度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆