Skip to content

Bitwise operations for math block #90

@dominik-korsa

Description

@dominik-korsa

Description

Add bitwise operations to math mode blocks:

  • & bitwise and
  • | bitwise or
  • ^ bitwise xor

and optionally:

  • ~ bitwise not (this might be tricky with Lua's doubles)
  • << bitshift left (multiplying by powers of 2)
  • >> bitshift right (integer division by powers of 2)

Advantages

This would be helpful for storing many states compactly and managing complex dependencies.

Existing solutions

I don't think it's currently possible for numbers of arbitrary size.

Disadvantages

  1. Lua uses doubles for everything, behaviour will be confusing for numbers above 2^53 due to rounding errors (https://www.lua.org/pil/2.3.html).
  2. The behaviour for non-integer values must be decided. Do we round them to the nearest integer before applying the bitwise operations?
    What if the user cares about "bits" 2^-1, 2^-2, 2^-3 etc.? This would be an unusual use-case, but technically possible with doubles.

My use case

I'm making an interlocking device for a railway. Each of the paths the train can take through the station (there are 28 variants in my case) has logic dependencies based on the states of each track switch, exit block, occupation of track segments etc.

The current states of each device and segment (non-)occupation can be represented as a single integer, where each bit represents the state of each device. If we for example have 2 switches and 2 track segments with occupancy detection we can represent the state as the sum of:

  • 32 if switch A is in position +
  • 16 if switch A is in position -
  • 8 if switch B is in position +
  • 4 if switch B is in position -
  • 2 if segment X is free
  • 1 if segment Y is free

The dependencies of a train path can also be represented as bitwise masks on this state.

If a path requires switch A to be in position +, switch B in position - and segment X to be free, we can represent the mask as:
MASK = 32 + 4 + 2 = 100000_2 + 000100_2 + 000010_2 = 100110_2 = 37
(in many cases the | will be preferable over a simple +)

To check if all dependencies of the path are fulfilled we can simply check if:
(STATE & MASK) ^ MASK == 0 or equally in this case STATE & MASK == MASK.
This means i need only 2 math blocks per train path, greatly reducing the complexity of the interlocking device.

A similar bit-based system can then be used to control the lights that light up on the control panel, the train signals which need to show and the devices of which switching should be locked.

This is the actual values for my dependencies:
image

Attachments

Issue checklist

  • I have thoroughly searched this repository for issues and pull requests requesting similar features. Duplicates will be closed.
  • I have set an appropriate title for this issue

Metadata

Metadata

Assignees

No one assigned

    Labels

    requestNew feature request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions