Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/redis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Swift中获取bool的位模式_Swift_Int_Boolean_Type Conversion_Bit Manipulation - Fatal编程技术网

在Swift中获取bool的位模式

在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

在ObjC中,布尔位模式可以通过将其转换为UInt8来检索

e、 g

  • 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