Swift 中奇怪的 UInt64 行为

Posted

技术标签:

【中文标题】Swift 中奇怪的 UInt64 行为【英文标题】:Weird UInt64 behavior in Swift 【发布时间】:2014-11-30 18:22:36 【问题描述】:

所以我一直在玩 BigInteger 实现,我发现了一些奇怪的东西......

这段代码:

let largeInt: UInt64 = UInt64(pow(Double(2), Double(64)))

我预计它会崩溃..但 largeInt 等于 0。之后,如果我尝试使用 largeInt,我会得到意想不到的结果。

例如,这个:

let int1: UInt64 = largeInt - 1

再一次,我预计它会崩溃(0 - 1 显然不是有效的无符号整数)。但是,在调试器中它不会崩溃,我看到一个值为 3472 (??)。关于发生了什么的任何想法?

编辑: 实际上,看起来第二行确实会导致崩溃,但直到函数结束(我在设置 int1 后的行上有一个断点)。 largeInt 仍然不会导致崩溃。

【问题讨论】:

【参考方案1】:

这对我来说似乎是一个错误。

let p1 = pow(Double(2), Double(64))

大于UInt64.max,因此

let x1 = UInt64(p1)

应该崩溃(或者可能返回 UInt64.max 作为近似值)。

“下一个较小的”浮点双精度变量

let p2 = nextafter(p1, 0.0)
let x2 = UInt64(p2)
// 18446744073709549568

被正确转换,并且“下一个更大”的浮点双变量 无法正确转换

let p3 = nextafter(p1, DBL_MAX)
let x3 = UInt64(p3)
// fatal error: floating point value can not be converted to UInt64
// because it is greater than UInt64.max

【讨论】:

这确实感觉像一个错误。 let largeInt: UInt64 = UInt64(pow(Double(2), Double(64)) + 100) 也是 0。让我怀疑他们有一个 >,而他们应该有一个 >=。但是let largeInt: UInt64 = UInt64(pow(Double(2), Double(65)) 确实崩溃了。 @RobNapier: UInt64(pow(Double(2), Double(64)) + 100) 也为零,因为pow(Double(2), Double(64)) + 100 等于pow(Double(2), Double(64)) 作为Double。使用下一个较大的数字(可表示为 Double),转换为 UInt64 会崩溃。

以上是关于Swift 中奇怪的 UInt64 行为的主要内容,如果未能解决你的问题,请参考以下文章

列表理解中奇怪的 lambda 行为

Chrome中奇怪的document.cookie行为[重复]

Xcode中奇怪的promiseKit 6语法行为

iPhone 应用程序中奇怪的 OpenGL ES 行为

iphone中奇怪的UISearchBar取消按钮行为(在模拟器中工作正常)

Eclipse 中奇怪的后退按钮(Alt-Left)行为