Skip to content

Instantly share code, notes, and snippets.

@deevis
Last active July 22, 2021 16:29
Show Gist options
  • Save deevis/bfd585ae37fad761c842c5d1033c4762 to your computer and use it in GitHub Desktop.
Save deevis/bfd585ae37fad761c842c5d1033c4762 to your computer and use it in GitHub Desktop.
Working with bitflags in Ruby
# our flags ordered by the bit that they'll toggle
# new flags MUST be added to the BEGINNING of the array!
FLAGS = [:a, :b, :c, :d, :e, :f]
build_flags = -> (*performed) { n = FLAGS.length; val = 0; FLAGS.each{|v| n -= 1; val += 2 ** n if performed.index(v)}; val}
required = build_flags.(:a, :b, :c, :f)
=> 57
required.to_s(2)
=> "111001"
performed = build_flags.(:b, :c, :f)
=> 41
performed.to_s(2)
=> "101001"
required_but_not_performed = (required ^ performed)
=> 16
required_but_not_performed.to_s(2)
=> "10000"
# and then to answer how to interpret the flags:
interpret_flags = ->(bitflag_val) { flag_count = FLAGS.length; set_flags = []; flag_count.times{|n| bit_position = flag_count - n; set_flags << FLAGS[n] if (bitflag_val >> (bit_position - 1)) & 1 == 1 }; set_flags}
interpret_flags.(required)
=> [a:, :b, :c, :f]
interpret_flags.(performed)
=> [:b, :c, :f]
interpret_flags.(required_but_not_performed)
=> [:a]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment