在Swift中获取bool的位模式
在ObjC中,布尔位模式可以通过将其转换为UInt8来检索 e、 g在Swift中获取bool的位模式,swift,int,boolean,type-conversion,bit-manipulation,Swift,Int,Boolean,Type Conversion,Bit Manipulation,在ObjC中,布尔位模式可以通过将其转换为UInt8来检索 e、 g true=>0x01 false=>0x00 然后,该位模式可用于进一步的位操作操作 现在我想在斯威夫特做同样的事情 到目前为止我工作的是 UInt8(UInt(boolValue)) 但这似乎不是首选方法 我还需要O(1)中的转换,而不需要依赖于数据的分支。所以,像下面这样的东西是不允许的 boolValue ? 1 : 0 此外,是否有一些关于UInt8和UInt初始值设定项实现方式的文档?e、 如果要从bool
- true=>0x01
- false=>0x00
现在我想在斯威夫特做同样的事情 到目前为止我工作的是
UInt8(UInt(boolValue))
但这似乎不是首选方法
我还需要O(1)中的转换,而不需要依赖于数据的分支。所以,像下面这样的东西是不允许的
boolValue ? 1 : 0
此外,是否有一些关于UInt8和UInt初始值设定项实现方式的文档?e、 如果要从bool转换的UInt初始值设定项使用依赖于数据的分支,我也不能使用它
当然,回退总是使用进一步的位操作来完全避免布尔值(例如)
- Swift是否提供了一种优雅的方式来访问Bool的位模式/将其转换为UInt8(在O(1)中),而无需依赖于数据的分支
- 如有疑问,请查看生成的汇编代码:)
使用(“-O”=“使用优化编译”)
使用两个函数调用可能效率不高。(事实并非如此
编译,如果你只输入代码>导入SWIFT < /代码>,没有基础。
现在,假设数据相关分支的另一种方法是:
func bar(someBool : Bool) -> UInt8 {
let x = UInt8(someBool ? 1 : 0)
return x
}
汇编代码是
.globl __TF4main3barFSbVSs5UInt8
.align 4, 0x90
__TF4main3barFSbVSs5UInt8:
pushq %rbp
movq %rsp, %rbp
andb $1, %dil
movb %dil, %al
popq %rbp
retq
.globl_uutf4main3barfsbvs5uint8
.对齐4,0x90
__TF4MAIN3BARFSBSS5UINT8:
pushq%rbp
movq%rsp,%rbp
和B$1,%dil
movb%dil,%al
popq%rbp
retq
没有分支,只是一个带有0x01
的“AND”操作
因此,我认为没有理由不使用这种“直接”转换。
然后,您可以使用仪器进行配置,以检查它是否是
你的应用程序。@martin-r的答案更有趣:-),但这可以在操场上完成
// first check this is true or you’ll be sorry...
sizeof(Bool) == sizeof(UInt8)
let t = unsafeBitCast(true, UInt8.self) // = 1
let f = unsafeBitCast(false, UInt8.self) // = 0
我也检查了它,生成的汇编代码与UInt8(someBool?1:0)完全相同。这就是为什么我仅限于回答“安全”方法:)有趣的是,我对我更喜欢哪种语法感到矛盾,因为比特转换清楚地表明代码的意图非常容易阅读,但又是不安全的……这确实很有趣。我敢打赌,非安全比特广播只会复制字节。但是一个enum的unsafeBitCast(从5个case到UInt8)实际上对0x07执行AND,因此编译器使用真正使用的位的信息。有点喜欢这种语法,因为编译器可能会改变它处理第一个答案的方式。虽然不安全,但此解决方案更明确。尽管如此,第一个答案提供了如何实际检查编译可能无法按假设工作的见解。我会接受这个答案,因为空速的名声不太好。 $ xcrun -sdk macosx swift-demangle __TFE10FoundationSb19_bridgeToObjectiveCfSbFT_CSo8NSNumber __TFE10FoundationSuCfMSuFCSo8NSNumberSu _TFE10FoundationSb19_bridgeToObjectiveCfSbFT_CSo8NSNumber ---> ext.Foundation.Swift.Bool._bridgeToObjectiveC (Swift.Bool)() -> ObjectiveC.NSNumber _TFE10FoundationSuCfMSuFCSo8NSNumberSu ---> ext.Foundation.Swift.UInt.init (Swift.UInt.Type)(ObjectiveC.NSNumber) -> Swift.UInt
let x = UInt8(NSNumber(bool: someBool).unsignedLongValue)
func bar(someBool : Bool) -> UInt8 {
let x = UInt8(someBool ? 1 : 0)
return x
}
.globl __TF4main3barFSbVSs5UInt8
.align 4, 0x90
__TF4main3barFSbVSs5UInt8:
pushq %rbp
movq %rsp, %rbp
andb $1, %dil
movb %dil, %al
popq %rbp
retq
// first check this is true or you’ll be sorry...
sizeof(Bool) == sizeof(UInt8)
let t = unsafeBitCast(true, UInt8.self) // = 1
let f = unsafeBitCast(false, UInt8.self) // = 0