Bitwise Operators – Least-Significant Bit Indexing

bitbitwise-operatorsindexing

Question

Is there a rough consensus if the bitmask 0x01 is properly said to have the "zeroth" bit set, or the "first" bit set?

If there isn't rough consensus that there's a generally right answer, is there at least rough consensus that there is a contextually right answer (e.g. that how the code is semantically using the bits determines the answer)?

Background

To be clear, I am generally familiar with low-level coding, and am thus comfortable with zero-indexing, but being a human raised in normal human cultures, I am comfortable with one-indexing as well. I am familiar with arguments for both sides. I also read every other question+answers that were suggested to me as I wrote this which seemed to deal with this sort of issue, but none of them were really immediately applicable to bits.

See, if we were talking about arrays, or sequences, or whatever else, I'd find it fairly easy to decide – if dealing with a sufficiently low-level language or platform (where indexes map very directly to offsets or have other convenient properties if zero-indexed), or with people who have zero-indexing ingrained I'd pick that, when dealing with some higher-level abstractions where I expect more "natural" human counting habits, I'd pick the other.

But bits… bits are in this perverse middle ground. Bit are both fundamentally abstract (digits of a number in binary: what's least-significant digit? I'd pick "first" over "zeroth", because this is counting, not indexing) but also highly relevant to extremely low-level work, where the zero-indexing is natural and useful (want just the nth bit? Shift 1 by n).

Motivation

In practice, this came up because I can't decide between these two C code snippets:

/* Bits are one-indexed - even in C, this feels more natural */
#define UCHAR_NTH_BIT_m(n) (unsigned char )(1 << ((n) - 1))
/* Bits are zero-indexed - this feels "purer" in some ways */
#define UCHAR_NTH_BIT_m(n) (unsigned char )(1 << (n))
/* NOTE: undefined behavior if (n < 1) or (n < 0), respectively. */

Best Answer

Is there a rough consensus if the bitmask 0x01 is properly said to have the "zeroth" bit set, or the "first" bit set?

Your question wouldn't have passed an honest pollsters(oxymoron?) sniff test because it was leading. Of course if you had your question might not have been around long. Try this,

Q: Which bit is on in this, 0x01, assuming little endian?

IMHO you would have received answers that said either / or , bit zero or lsb. It is highly unlikely that any 'coder'("I am not an animal") would have said bit one.

Is 2 to the power of 0 = 1 or is 2 to the power of 1 = 1? Humans imply zero offsets without thought, e.g How old are you? How far is it from your house to work?

My specific answer to this,

#define UCHAR_NTH_BIT_m(n) (unsigned char )(1 << ((n) - 1))

is Please don't. because no human will be looking at it, only 'coders'.