Skip to content

Add Big Endian for getbits() and setbits() #537

Closed
dzid26 wants to merge 3 commits into
berry-lang:masterfrom
dzid26:bits
Closed

Add Big Endian for getbits() and setbits() #537
dzid26 wants to merge 3 commits into
berry-lang:masterfrom
dzid26:bits

Conversation

@dzid26

@dzid26 dzid26 commented Jun 17, 2026

Copy link
Copy Markdown

Changes:

  • Analogously to get(), set(), the negative length arg in getbits() and setbits() sets Big Endian for reading and writing bits.
  • Analogously to get(), zero length in getbits() will return nil
  • Bunch of testcases for bit reading/writing

The need for this came about when reading signals in CAN messages in my little project where I chose Berry for scripting car automations.

There are some interesting variations how bit numbering within a byte can be interpreted. People refer to them as in/consistent, lsb0/msb0 and normal/inverted. It gets pretty confusing especially when thinking of data spanning multiple bytes. lsb0/msb0 is meaningless to me if bits can be inverted...

Let's just say that for working with a single data at the time that is in a code and not sent over a medium, only one numbering makes sense for Big Endian - msb0, consistent or normal.


Now why would anyone use different numberings?
One reason is that at low level the hardware may have bits ordered differently and perhaps we want to stream uncompressed bits over a medium, it is often better to start with MSB. Just like in numbering in English language. And unlike numbering in German which is objectively worse. Einundzwanzig.

Second reason is visualization of mixed endianness data. If have bytes incrementing down, the little endian starts in right top corner and big endian ends in left top corner. People want to have just one table header, so they fiddle with bits numbering

This is the for CANbus - the signal definition file (DBC) allows to define mixed signals in one byte array and so it uses inverted bits numbering for big endian to make visualisation indexing constant.
In Kvaser software the table is indexed using Little Endian interpretation, but we can insert Big Endian signal into it
image
It's MSB is on 7th bit in 0th byte and that's exactly how its offset is defined in DBC file.

If I put 0 as an offset in DBC, I would get this abomination:
image

So that's pretty terrible numbering.


We don't care about making drawings mixed endianness signals in a table. - Setbit/getbits functions always works with one signal at the time. And we don't interface with transmission mediums directly. - So we do the only reasonable thing and define signal with normal numbering, so 0 offset will give us fully filled byte. Example - first little endian:

# Little Endian
> bytes(-3).setbits(0, 12, 0xFFF)  
bytes('FF0F00')
image

And big endian:

# Big Endian
> bytes(-3).setbits(0, -12, 0xFFF) 
bytes('FFF000')

All we have to do to visualize Big Endian is redraw bit indexes header in MS Paint to match Big Endian normal aka consistent bit order:
image


Side note, for converting CANbus DBC inverted offset to this normal big endian offset, all I have to do is off + 7 - 2*(off % 8) .
Side note 2, I kinda want to add getibits and setibits helpers for arbitrary length signed integers...

dzid26 added 3 commits June 16, 2026 23:08
re-solidified getbits setbits
- proto vargs hints BE_VA_METHOD (2) now
- spaces got replaced with tabs
@s-hadinger

Copy link
Copy Markdown
Contributor

Thanks, very useful.
As a matter of fact, I was just about to move setbits/getbits to native C instead of solidified code. So I will probably merge and transpose your changes to the native implementation.

@s-hadinger

Copy link
Copy Markdown
Contributor

Thanks, this is superseded by #538

@s-hadinger s-hadinger closed this Jun 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants