如何修复‘Integer literal '2147483648'存入Int时溢出’异常?
解决Int字面量溢出问题:判断32位整数最高位是否为1
问题原因
你遇到的溢出问题,本质是Swift中Int的位数和平台相关:在32位系统上,Int是32位有符号整数,范围是-2^31到2^31-1(也就是-2147483648到2147483647)。而0x80000000对应的十进制是2147483648,刚好超过了32位有符号Int的最大值,所以编译器会报错“Integer literal overflows when stored into 'Int'”。
另外,你的原始数据是4字节(32位)的十六进制值,所以更适合用固定位数的整数类型来处理,而不是依赖平台相关的Int。
解决方案1:使用UInt32处理(推荐)
既然原始数据是32位,直接用无符号32位整数UInt32来操作,就能避免溢出问题,因为UInt32的范围是0到2^32-1,0x80000000完全在这个范围内。
修改转换函数
func checkHexToUInt32(stringData: String) -> UInt32? { guard let num = UInt32(stringData, radix: 16) else { return nil } return num } // 使用示例 let stringData = "84121516" guard let value = checkHexToUInt32(stringData: stringData) else { // 处理转换失败的情况(比如输入不是合法十六进制) fatalError("Invalid hex string") } let checkEngineLightOn = (value & 0x80000000) != 0
或者不修改原函数,转换时转成UInt32
如果你不想改动原有的checkHexToInt函数,可以在运算前把Int值转成UInt32:
let stringData = "84121516" guard let intValue = checkHexToInt(stringData: stringData), let uintValue = UInt32(exactly: intValue) else { // 处理转换失败或值超出UInt32范围的情况 fatalError("Invalid value or out of range") } let checkEngineLightOn = (uintValue & 0x80000000) != 0
解决方案2:用Int32判断符号位
32位有符号整数Int32的最高位是符号位,当最高位为1时,数值会是负数。所以可以把值转成Int32,直接判断是否小于0:
let stringData = "84121516" guard let intValue = checkHexToInt(stringData: stringData), let int32Value = Int32(exactly: intValue) else { fatalError("Invalid value or out of range") } let checkEngineLightOn = int32Value < 0
这种方式不需要使用0x80000000字面量,自然避免了溢出问题。
额外提示
尽量不要用!强制解包可选值,像上面示例中用guard let或if let处理,能避免因转换失败导致的崩溃。
内容的提问来源于stack exchange,提问作者tp2376
相关产品推荐
相关产品推荐

