gpt4 book ai didi

swift - 为什么 Int(Float(Int.max)) 给我一个错误?

转载 作者:搜寻专家 更新时间:2023-10-31 08:17:38 24 4
gpt4 key购买 nike

我观察到一些非常奇怪的事情。如果您在 Swift 中运行此代码:

Int(Float(Int.max))

它崩溃并显示错误消息:

fatal error: Float value cannot be converted to Int because the result would be greater than Int.max

这确实是违反直觉的,所以我将表达式扩展为 3 行,并尝试在 playground 中查看每一步发生的情况:

let a = Int.max
let b = Float(a)
let c = Int(b)

它崩溃并显示相同的消息。这次,我看到 a 是 9223372036854775807,b 是 9.223372e+18。很明显 ab 大了 36854775807。我也明白 float 是不准确的,所以我期望小于 Int.max,最后几位为 0。

我也用 Double 试过了,它也崩溃了。

然后我想,也许这就是 float 的行为方式,所以我在 Java 中测试了同样的事情:

long a = Long.MAX_VALUE;
float b = (float)a;
long c = (long)b;
System.out.println(c);

它打印出预期的 9223372036854775807!

swift 有什么问题?

最佳答案

DoubleFloat 的尾数中没有足够的位来准确表示 19 有效数字,因此您得到四舍五入的结果。

如果使用 String(format:) 打印 Float,您可以看到 Float 值的更准确表示:

let a = Int.max
print(a) // 9223372036854775807
let b = Float(a)
print(String(format: "%.1f", b)) // 9223372036854775808.0

所以Float表示的值比Int.max1


许多值将被转换为相同的 Float 值。现在的问题是,在产生不同的 DoubleFloat 值之前,您必须减少多少 Int.max

Double 开头:

var y = Int.max

while Double(y) == Double(Int.max) {
y -= 1
}

print(Int.max - y) // 512

因此对于 Double,最后的 512 Int 都转换为相同的 Double

Float 用于表示值的位数较少,因此有更多值都映射到相同的 Float。切换到 - 1000 以便它在合理的时间内运行:

var y = Int.max

while Float(y) == Float(Int.max) {
y -= 1000
}

print(Int.max - y) // 274877907000

因此,您对 Float 可以准确表示特定 Int 的期望是错误的。


跟进评论中的问题:

If float does not have enough bits to represent Int.max, how is it able to represent a number one larger than that?

float 由两部分表示:尾数和指数。尾数表示有效数字(二进制​​),指数表示 2 的幂。因此, float 可以通过尾数 1 和表示幂的指数来准确表示 2 的偶次幂。

甚至不是 2 的幂的数字可能有一个二进制模式,其中包含比尾数中可以表示的更多的数字。 Int.max(即 2^63 - 1)就是这种情况,因为在二进制中是 1111111111111111111111111111111111111111111111111111111111111(63 个 1)。 32 位的 Float 不能存储 63 位的尾数,因此必须对其进行舍入或截断。在 Int.max 的情况下,向上舍入 1 的结果是值100000000000000000000000000000000000000000000000000000000000000。从左边开始,只有 1 个有效位要用尾数表示(后面的 0 是免费的),所以这个数是 1 的尾数和 64 的指数。

有关 Java 正在做什么的解释,请参阅@MartinR 的回答。

关于swift - 为什么 Int(Float(Int.max)) 给我一个错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43706635/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com