ChatGPT解决这个技术问题 Extra ChatGPT

Bitwise operators and "endianness"

Does endianness matter at all with the bitwise operations? Either logical or shifting?

I'm working on homework with regard to bitwise operators, and I can not make heads or tails on it, and I think I'm getting quite hung up on the endianess. That is, I'm using a little endian machine (like most are), but does this need to be considered or is it a wasted fact?

In case it matters, I'm using C.

IMHO, these are slightly different questions. This question is like "is 128 << 2 == 512 on any CPU?", that question is like "does 128 << 2 lay out as 0x02 0x00 on any CPU?".

M
Michael

Endianness only matters for layout of data in memory. As soon as data is loaded by the processor to be operated on, endianness is completely irrelevent. Shifts, bitwise operations, and so on perform as you would expect (data logically laid out as low-order bit to high) regardless of endianness.


Shouldn't it be "high to low order bit" logically?
@legends2k: had same thought
@legends2k: yes. Left shift = multiply by power of 2. Right shift = divide by power of 2 (with different rounding than integer division for negative values).
@JoshC: No, the PDP-10 would just perform the operation as it's logically defined on the data, regardless of exactly which bit is laid out where in its memory/registers. Consider: when you add two 32-bit integers, you don't worry about the processor having to convert the data in order for the addition to work (nor do you worry about the order of bits in a byte in the hardware) - the ALU just does the "right thing", because it's wired in a way that works with its hardware. The shifts are the same way - they operate on the data in a way that abstracts out the hardware's byte/bit order details.
@JoshC: (cont.) And in C, the bit shift operators are defined in a way that abstracts them even more: they are defined in terms of the values they produce, not in terms of the way they move the underlying bits around (so if you're on some obscure platform where a hardware bit-shift instruction would produce an invalid bit layout, e.g. you've shifted a value bit into a padding bit, a conforming compiler is required to produce instructions which work around that, as I understand it).
l
legends2k

The bitwise operators abstract away the endianness. For example, the >> operator always shifts the bits towards the least significant digit. However, this doesn't mean you are safe to completely ignore endianness when using them, for example when dealing with individual bytes in a larger structure you cannot always assume that they will fall in the same place.

short temp = 0x1234;
temp = temp >> 8;

// on little endian, c will be 0x12, on big endian, it will be 0x0
char c=((char*)&temp)[0];

To clarify, I am not in basic disagreement with the other answers here. The point I am trying to make is to emphasise that although the bitwise operators are essentially endian neutral, you cannot ignore the effect of endianess in your code, especially when combined with other operators.


You are basically disagreeing with everyone but yet your answer was voted the best. How can identify the behaviors?
I have added some further clarification
So to further clarify you mean if unless I am actually retrieving values in bytes it all fine?
O.o so >> and << aren't right or left shift at all; they're "shift towards least significant, and shift towards most significant". that makes "division and multiplication by shifting" endianness independant... now im confused if casting via memcpy would mess this up.
r
rpetrich

As others have mentioned, shifts are defined by the C language specification and are independent of endianness, but the implementation of a right shift may vary depending on iff the architecture uses one's complement or two's complement arithmetic.


P
Peter Mortensen

It depends. Without casting the number into a new type, you can treat the endianness transparently.

However, if your operation involves some new type casting, then use your caution.

For example, if you want right shift some bits and cast (explicitly or not) to a new type, endianness matters!

To test your endianness, you can simply cast an int into a char:

int i = 1;

char *ptr;

...

ptr = (char *) &i;  //Cast it here

return  (*ptr);

... Or create a union... {union { int i = 1; char a[4];} b;return b.a[3] == 1;} //big endian
m
mmx

You haven't specified a language but usually, programming languages such as C abstract endianness away in bitwise operations. So no, it doesn't matter in bitwise operations.


Given that the question has no revisions, I'm surprised you say he hasn't mentioned language, when he does, and it's also tagged as C.
@Simeon: It didn't have at the time I wrote this answer. Edits by a single author in a small time frame will be merged into one. That's why you're seeing it as a single revision.