43

I'm reading "Learning Core Audio: A Hands-On Guide to Audio Programming for Mac and iOS" by Chris Adamson and at one point the author describes big-endian as:

the high bits of a byte or word are numerically more significant than the lower ones.

However, until now I thought the problem of big-little endian only applies to byte order and not bit order. One byte has the same bit order (left to right) no matter if we're talking about little endian or big endian systems. Am I wrong? Is the author wrong? Or did I misunderstood his point?

S.B
  • 13,077
  • 10
  • 22
  • 49
Meda
  • 2,776
  • 4
  • 20
  • 31
  • Am unsure about audio but in video, I have come across a typical question in an interview; for example, in a situation, if you would want to have a 32 bit value get represented in 24 bits. then the lower bits are generally discarded since it is of to the fact that the higher 24 bits represent/has more information. Was the author somehow mentioning this. – Adit Ya Apr 05 '18 at 08:01
  • 1
    Although Michael Burr's answer is sufficient for learners, other answers go into deeper aspects of bit-endian-ness and C, especially [@Nominal Animal](https://stackoverflow.com/a/49622327/2410359). As OP has not been here since 2015, I doubt the selected answer will change. – chux - Reinstate Monica Apr 12 '18 at 15:36

6 Answers6

39

Since you can't normally address the bits within a byte individually, there's no concept of "bit endianness" generally.

Michael Burr
  • 333,147
  • 50
  • 533
  • 760
  • 9
    But, when you do bitwise operations like shifting, don't you "address" them? – Meda May 29 '13 at 00:06
  • 8
    When shifting, you still deal with the bits as part of a larger unit (byte, int or something). Endianess only matters when you can directly address a larger object byte-by-byte - you need to know how those individually addressable bytes are arranged within the larger object. – Michael Burr May 29 '13 at 00:08
  • 5
    @Meda when you're down to the level of bit-shifting a single byte it's "representation" (the number it corresponds to) can break down and it's just an arbitrary collection of 1's and 0's. The instructions passed along to rotate (ROL, ROR, RCL, RCR) or shift (SHL, SHR...) in a given "direction" are as abstract as the numbers themselves. – Nick T May 29 '13 at 00:20
  • 10
    @Meda: Bitwise operations work it terms of bit-positions in the abstract binary representation of a number, not in terms of physical machine bits. For this reason they are completely independent of endianness. There's nothing that prevents these operations from existing in ternary machines, which has no physical bits at all. In C, shifting a positive value 1 bit to the left is always guaranteed to multiply it by 2, regardless of endianness. – AnT stands with Russia May 29 '13 at 02:52
  • But if you could address bits, the concept is equally applicable. – kchoi Apr 11 '18 at 22:33
  • 1
    Only if you are not doing system programming. – Galaxy Sep 16 '18 at 03:56
  • It's actually really common in graphics, especially older bitplane graphics on VGA/EGA and various video game consoles of the 90's, to have different orders of significance to the order of the bits. You can address an entire bitplane across 8 columns by writing a single byte, and it matters whether the lowest index bit is considered the lowest/highest column (e.g. in the first byte, VGA set bit 0 to column 7 and bit 7 to column 0, whereas other systems would use bit 0 is column 0 - see `SDL_PIXELFORMAT_INDEX1LSB` and `QImage::Format_MonoLSB`). – Dwayne Robinson Jan 11 '21 at 09:26
  • Endianess refers to the order of the `bytes` when they are in RAM, in the hard disks, or when transmitted across a network. A byte value of `0x05` in binary bits is always represented as `00000101` and I have not encountered any situations where its representation can be in reverse order and thus becoming `10100000`. – daparic Feb 12 '21 at 19:50
32

This is not an answer to the stated question — it has been well answered by others already —, but a footnote explaining some of the terms in the hope that it will clarify the related concepts. In particular, this is not specific to at all.


  • Endianness and byte order

    When a value larger than byte is stored or serialized into multiple bytes, the choice of the order in which the component bytes are stored is called byte order, or endian, or endianness.

    Historically, there have been three byte orders in use: "big-endian", "little-endian", and "PDP-endian" or "middle-endian".

    Big-endian and little-endian byte order names are derived from the way they order the bytes: big-endian puts the most significant byte (the byte that affects the logical value most) first, with successive bytes in decreasing order of significance; and little-endian puts the least significant byte first, with successive bytes in increasing order of significance.

    Note that byte order may differ for integer types and floating-point types; they may even be implemented in separate hardware units. On most hardware they do have the same byte order, though.
     

  • Bit order

    Bit order is very similar concept to endianness, except that it involves individual bits rather than bytes. The two concepts are related, but not the same.

    Bit order is only meaningful when bits are serialized, for example via a serial or SPI or I2C bus; one after another.

    When bits are referred to in a larger group used in parallel, as one unit, like in a byte or a word, there is no order: there is only labeling and significance. (It is because they are accessed and manipulated as a group, in parallel, rather than serially one by one, that there is no specific order. Their interpretation as a group yields differing significance to each, and us humans can label or number them for ease of reference.)
     

  • Bit significance

    When a group of bits are treated as a binary value, there is a least significant bit, and a most significant bit. These names are derived from the fact that if you change the least significant bit, the value of the bit group changes by the smallest amount possible; if you change the most significant bit, the value of the bit group changes by the largest amount possible (by a single bit change).

    Let's say you have a group of five bits, say a, b, c, d, and e, that form a five-bit unsigned integer value. If a is the most significant, and e the least significant, and the three others are in order of decreasing significance, the unsigned integer value is
        value = a·24 + b·23 + c·22 + d·21 + e·20
    i.e.
        value = 16a + 8b + 4c + 2d + e

    In other words, bit significance is derived from the mathematical (or logical) interpretation of a group of bits, and is completely separate from the order in which the bits might be serialized on some bus, and also from any human-assigned labels or numbers.

    This is true for all bit groups that logically construct numerical values, even for floating-point numbers.
     

  • Bit labels or bit numbering

    For ease of reference in documentation for example, it is often useful to label the individual bits. This is essentially arbitrary; and indeed, I used letters a to f in an example above. More often, numbers are easier than letters — it's not that easy to label more than 27 bits with single letters.

    There are two approaches to label bits with numbers.

    The most common one currently is to label the bits according to their significance, with bit 0 referring to the least significant bit. This is useful, because bit i then has logical value 2i.

    On certain architectures' documentation, like IBM's POWER documentation, the most significant bit is labeled 0, in decreasing order of significance. In this case, the logical value of a bit depends on the number of bits in that unit. If an unit has N bits, then bit i has logical value of 2N-i-1.

    While this ordering may feel weird, these architectures are all big-endian, and it might be useful for humans to just remember/assume that most significant comes first on these systems.

    Remember, however, that this is a completely arbitrary decision, and in both cases the documentation could be written with the other bit labeling scheme, without any effect on the real-world performance of the systems. It is like choosing whether to write from left to right, or from right to left (or top-down, for that matter): the contents are unaffected, as long as you know and understand the convention.
     

While there is some correlation between byte order and bit labeling, all four of the above concepts are separate.

There is correlation between byte order and bit labeling — in the sense that the documentation for a lot of big-endian hardware uses bit labeling where the most significant bit is bit zero —, but that is only because of choises made by humans.

In , the order in which the C compiler packs bitfields in a struct, varies between compilers and architectures. It is not specified by the C standard at all. Because of this, it is usually a bad idea to read binary files into a struct type with bitfields. (Even if it works on some specific machine and compiler, there is no guarantee it works on others; often, it does not. So, it definitely makes the code less portable.) Instead, read into a buffer, and array of unsigned char, and use helper accessor functions to extract the bit fields from the array using bit shifts (<<, >>), binary ors (|), and masking (binary and, &).

Nominal Animal
  • 38,216
  • 5
  • 59
  • 86
26

The only sense in which there is such a thing as "bit order" is the order in which bits are assigned to bitfields. For instance, in:

union {
    struct {
        unsigned char a:4;
        unsigned char b:4;
    } bf;
    unsigned char c;
};

depending on the implementation, the representation of bf.a could occupy the high four bits of c, or the low four bits of c. Whether the ordering of bitfield members matches the byte order is implementation-defined.

R.. GitHub STOP HELPING ICE
  • 208,859
  • 35
  • 376
  • 711
  • 8
    Simplest example of this in the real world: https://github.com/freebsd/freebsd/blob/master/sys/netinet/ip.h#L51-L59 – Art Apr 04 '18 at 12:05
  • 1
    The fun thing is of course that in hexadecimals, the bytes are almost always displayed in big endian, i.e. the most significant nibble is displayed first. In other words, in hexadecimals, there is a difference in the order for the bits in the bytes and the bytes in the larger number / word. To me, his is just the way humans work; we tend to show things as big endian even if the underlying system is little endian. We're a mess ;) – Maarten Bodewes Feb 26 '23 at 13:09
14

The "endianness" of a byte in terms of bit-order is not really a concern unless you're working with an exotic system that allows you to address bits separately. It can be a concern when deciding how to transmit data over the wire, but this decision is usually made at a hardware level.

Audio

In terms of relevance to audio streaming, it could very well be important. The hardware which is responsible for converting the stream of digital audio into analogue audio signals may expect the bits in the stream to be in a particular order. If they're wrong, the sound might come out completely whacked. Perhaps the author of your book elaborates on this? Anyway, as I mentioned earlier, this is normally decided at a hardware level and is not really a concern when programming at a user or even a kernel level. Generally, industry standards will define how two pieces of hardware will transmit the data to each other. As long as all your hardware agrees on the bit endianness, then everything is fine.

Further reading at Wikipedia.

Community
  • 1
  • 1
Anthony
  • 12,177
  • 9
  • 69
  • 105
9

The order of bits inside a Byte does not make sense, bits inside a byte are not addressable so you can't define an order of this bits to use it as a reference for a definition of endianness. Unlike bits, bytes are addressable, so there is an address order that we can use as a reference to define what does little or big endian mean.

You may get the impression that Left shift << or Right Shift >> bit-wise operators imply indirectly that there is a defined order of bits inside a byte, but that's not true. This two terms are based on an abstract byte representation where the lowest bit is located at the right and bits get higher in value when going left, but by definition Left shift has the same effect as multiplication by 2, and Right shift has the same effect as division by 2 (for unsigned integers).

AlexDan
  • 3,203
  • 7
  • 30
  • 46
0

Bit 5 is bit at index 5, not the bit at the address of &byte+5bits. Your computer will understand all bit operations in terms of index bits, not physical bits.

Of course "bit endianness" still matter when you have to guarantee a certain sequence of bits, e.g. in network protocols or over peripheries such as an SPI bus for example, but in this case your library might say something like "data is always sent MSB first" which means each byte is sent with the most significant bit first, and that takes care of that.

glades
  • 3,778
  • 1
  • 12
  • 34