Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bitwise operations for math block #90

Open
2 tasks done
dominik-korsa opened this issue Sep 27, 2024 · 1 comment
Open
2 tasks done

Bitwise operations for math block #90

dominik-korsa opened this issue Sep 27, 2024 · 1 comment
Labels
request New feature request

Comments

@dominik-korsa
Copy link

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
@dominik-korsa dominik-korsa added the request New feature request label Sep 27, 2024
@dominik-korsa
Copy link
Author

I'm willing to implement this, either as part of The Modpack or as a separate mod. I do however believe that this change fits The Modpack and could be implemented here trivially, while creating a separate mod would lead to more fragmentation and be unnecessarily cumbersome.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
request New feature request
Projects
None yet
Development

No branches or pull requests

1 participant