将数字分解为2的幂

时间:2019-05-23 19:09:02

标签: swift for-loop bit-manipulation

您好,对于我要通过点击收集系统编写的iOS应用,我需要将数字分解为5的2的幂。

该系统的后端用c#编写,并使用以下代码将多个选项列表作为单个数字保存在数据库中,例如:

在订购系统上为填充卷选择沙拉的做法如下:

library(fuzzyjoin)
df.sample %>%
  mutate(sample_time = lubridate::ymd_hm(paste(date, hour, min))) %>%
  fuzzy_left_join(df.state, 
                  by = c("id" = "id",
                         "sample_time" = "starttime",
                         "sample_time" = "endtime"),
                  match_fun = list(`==`, `>=`, `<=`))

   id.x       date hour min value         sample_time id.y           starttime             endtime state
1     A 2018-11-12    8  47    70 2018-11-12 08:47:00 <NA>                <NA>                <NA>  <NA>
2     A 2018-11-12    8  59    70 2018-11-12 08:59:00    A 2018-11-12 08:59:00 2018-11-12 15:57:00  Pass
3     A 2018-11-12    9   6    86 2018-11-12 09:06:00    A 2018-11-12 08:59:00 2018-11-12 15:57:00  Pass
4     A 2018-11-12    9  18    86 2018-11-12 09:18:00    A 2018-11-12 08:59:00 2018-11-12 15:57:00  Pass
5     A 2018-11-12   13  22    86 2018-11-12 13:22:00    A 2018-11-12 08:59:00 2018-11-12 15:57:00  Pass
6     A 2018-11-12   13  36    74 2018-11-12 13:36:00    A 2018-11-12 08:59:00 2018-11-12 15:57:00  Pass
7     A 2018-11-12   16  12    81 2018-11-12 16:12:00 <NA>                <NA>                <NA>  <NA>
8     A 2018-11-14    6  32    77 2018-11-14 06:32:00    A 2018-11-14 06:24:17 2018-11-14 17:22:16  Pass
9     A 2018-11-14    7  12    79 2018-11-14 07:12:00    A 2018-11-14 06:24:17 2018-11-14 17:22:16  Pass
10    A 2018-11-14   19  21    83 2018-11-14 19:21:00 <NA>                <NA>                <NA>  <NA>
11    A 2018-11-12    7  47    91 2018-11-12 07:47:00 <NA>                <NA>                <NA>  <NA>

通过使用这种方法,将选项保存为(生菜+番茄+洋葱)= 21(1 + 4 + 16)

另一方面,我使用c#函数执行此操作:

lettuce = 1
cucumber = 2
tomato = 4
sweetcorn = 8
onion = 16

我需要将此函数转换为swift 5格式,以将解码器集成到我的iOS应用中

任何帮助将不胜感激

3 个答案:

答案 0 :(得分:1)

在Swift中,这些位字段表示为选项集,它们是符合OptionSet protocol的类型。这是您的用例示例:

struct Veggies: OptionSet {
    let rawValue: UInt32

    static let lettuce = Veggies(rawValue: 1 << 0)
    static let cucumber = Veggies(rawValue: 1 << 1)
    static let tomato = Veggies(rawValue: 1 << 2)
    static let sweetcorn = Veggies(rawValue: 1 << 3)
    static let onion = Veggies(rawValue: 1 << 4)
}

let someVeggies: Veggies = [.lettuce, .tomato]
print(someVeggies) // => Veggies(rawValue: 5)

print(Veggies.onion.rawValue) // => 16

OptionSet优于仅使用其原始值,这有两个原因:

1)它们标准化了案例的名称,并提供了一种与这些值进行交互的一致且简便的方法 2)OptionSet源自SetAlgebra协议,并为许多有用的方法(例如unionintersectionsubtractcontains,等

但是,我会提防这种设计。选项集仅在标记数量很少(少于64个)且无法预见扩展时才有用。它们实际上是基本的,除了“ x存在或不存在”之外,不能存储任何有效载荷,并且它们主要用于对性能和内存使用具有非常高的敏感性的用例,这种情况在当今非常罕见。我建议使用常规对象(素食类,存储名称和任何其他相关数据)代替。

答案 1 :(得分:0)

您可以像这样使用while循环:

var j = 0
while j < 32 {
    var mask = 1 << j
    j += 1
}

Here是Swift 5中有关循环和控制流的链接。

答案 2 :(得分:0)

嗨,我知道这是我的最终解决方案:

    var salads = "" as String
    let value = 127
    var j=0
    while j < 256 {

        let mask=1 << j
        if((value & mask) != 0) {
            salads.append(String(mask) + ",")
        }
        j += 1
    }
    salads = String(salads.dropLast()) // removes the final ","
    print(salads)

现在,这很好地输入到我的SQL查询中的in子句中,谢谢大家的帮助! :)