Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Bitwise Fun with Elixir

Wu Qing
December 19, 2020

Bitwise Fun with Elixir

For most web developers, bitwise operations are not very familiar, but in some situations they can be quite useful and they are by nature super performant. In this talk, I'll try to lead the audience to have some fun with bitwise operations in Elixir.
Presented at Elixir Australia December 2020 Meetup:
https://www.meetup.com/elixir-sydney/events/zrlnzrybcqbvb/

Recording video available at https://www.youtube.com/watch?v=NR_Jk3yUEqc

Wu Qing

December 19, 2020
Tweet

More Decks by Wu Qing

Other Decks in Programming

Transcript

  1. Why do I want to know these? 1. Useful •

    Bit fields • Communications Protocols • Embedded systems • Something fun 2. Performance
  2. FlagShihTzu: Bit fields for ActiveRecord class Subscription < ActiveRecord::Base include

    FlagShihTzu ... has_flags 1 => :requires_shipping, 2 => :signup_only, 3 => :recurring, ... 20 => :za_3p, 21 => :combined, 22 => :tablet, ... end
  3. Basic bitwise operations: shift # shift to the left by

    1 0b0000_0001 <<< 1 # -> 0b0000_0010 # shift to the right by 4 0b0101_0000 >>> 4 # -> 0b0000_0101
  4. Set fixed bit x y x or y 1 0

    1 0 0 0 1 0 1 1 0 1 0 0 0 1 0 1 0 1 1 0 0 0
  5. Set fixed bit 0b1011_0100 ||| 0b0000_0010 # -> 0b1011_0110 #

    or 0b1011_0100 ||| (1 <<< 1) # -> 0b1011_0110
  6. Set nth to mth bits Set 2th to 4th bits

    of 0b1001_0110 0b1001_0110 ||| (0b111 <<< 1) # -> 0b1001_1110
  7. Clear fixed bit x y x and y 1 1

    1 0 1 0 1 1 1 1 1 1 0 1 0 1 0 0 0 1 0 0 1 0
  8. Clear fixed bit 0b1011_0100 &&& 0b1111_1011 # -> 0b1011_0000 #

    or 0b1011_0100 &&& ~~~(1 <<< 2) # -> 0b1011_0000
  9. Clear nth to mth bits Clear highest three bits of

    0b1010_0101 0b1010_0101 &&& ~~~(0b111 <<< 5) # -> 0b0000_0101
  10. Read a group of bits Read 5rd to 8th bits

    from 0b1010_0101 (0b1010_0101 &&& 0b1111_0000) >>> 4 # -> 0b1010
  11. Secret Handshake Determine the actions of a secret handshake based

    on the binary representation of the given code. If the following bits are set, include the corresponding action in your list of commands, in order from lowest to highest. 1 = wink 10 = double blink 100 = close your eyes 1000 = jump 10000 = Reverse the order of the operations in the secret handshake
  12. Is the Bit Set? # code is the number we

    are given (code &&& 0b1) > 0 (code &&& 0b10) > 0 (code &&& 0b100) > 0 ...
  13. Secret Handshake Solution defmodule SecretHandshake do use Bitwise, only_operators: true

    @actions %{ 0b1 => "wink", 0b10 => "double blink", 0b100 => "close your eyes", 0b1000 => "jump", 0b10000 => nil } defguard bit_set?(code, mask) when (code &&& mask) > 0 @spec commands(code :: integer) :: list(String.t()) def commands(code) do Enum.reduce(@actions, [], fn {0b10000, _}, acc when bit_set?(code, 0b10000) -> acc {0b10000, _}, acc -> Enum.reverse(acc) {mask, action}, acc when bit_set?(code, mask) -> [action | acc] _, acc -> acc end) end end
  14. References Elixir Bitwise: https://hexdocs.pm/elixir/Bitwise.html Writing NES Games With Assembly: https://www.youtube.com/

    watch?v=kXbMCKMJXXQ&feature=youtu.be&t=484 NES Emulator Part #1: Bitwise Basics & Overview: https:// www.youtube.com/watch?v=F8kx56OZQhg