Simple bitwise manipulation for small-endian integers in large machines?

For a specific need, I create a four-byte integer of four byte characters using nothing special (on my small platform-end):

return (( v1 << 24) | (v2 << 16) | (v3 << 8) | v4); 

I know that an integer stored in a large-end machine will look like AB BC CD DE instead of DE CD BC AB small entity, although it will completely affect my operation, as I will move incorrectly or it will simply lead to the correct result which is stored in reverse order and should be discarded?

I was wondering if I need to create a second version of this function for (still unknown) bit manipulation for a large-end machine, or perhaps use the ntonl-related function, which I donโ€™t understand how it will be known if my number is in the correct order or not.

What will be your proposal to ensure compatibility, bearing in mind that I need to form integers in this way?

+4
source share
4 answers

As long as you work at a value level, there will be absolutely no difference in the results you get, regardless of whether your machine is small or large. That is, while you use language level operators (for example, | and << in your example), you will get exactly the same arithmetic result from the above expression on any platform. The specificity of the machine is not detected and not visible at this level.

The only situations where you need to take care of the content is that the data you are working with is considered at the level of the object's representation, that is, in situations where it is important to have a representation of raw memory. What you said above about โ€œ AB BC CD DE instead of DE CD BC AB โ€ specifically refers to the original location of the data memory. What functions as ntonl does: they convert one memory layout to another memory layout. Until you have indicated that the actual memory location is not important to you. It?

Again, if you only care about the meaning of the above expression, it is completely and completely independent of continent. Basically, you donโ€™t have to worry about content capability at all when you write C programs that donโ€™t try to access and study the contents of raw memory.

+8
source

although this will completely affect my operation, as I will move incorrectly (?)

No.

The result will be the same regardless of the endian architecture. Bit-shifting and twisting are like ordinary arithmetic operations. Is 2 + 2 the same at the small ends and large ends of the architecture? Sure. 2 << 2 will be the same.

Small and big problems with endian arise when you are dealing directly with memory. You will have problems with the following steps:

 char bytes[] = {1, 0, 0, 0}; int n = *(int*)bytes; 

On small end machines, n will be 0x00000001. On large finite machines, n will be 0x01000000. This is when you have to change the bytes.

+3
source

[Rewritten for clarity]

ntohl (and ntohs , etc.) is mainly used to move data from one machine to another. If you just manipulate the data on one machine, then this is perfect for shifting bits without any additional ceremony - the bit shift (at least in C and C ++) is determined from the point of view of multiplication / division by degree 2, therefore it works the same whether the machine is large or small.

When / if you need to (at least potentially) move data from one machine to another, it is usually recommended to use htonl before sending and ntohl when you receive it. It can be completely nops (in the case of BE BE), two identical conversions that cancel each other out (LE to LE) or actually lead to a byte break (LE to BE or vice versa).

+1
source

FWIW, I think a lot of what was said here is correct. However, if the programmer is entity encoded, say, using masks for bitwise inspection and manipulation, cross-platform results may be unexpected.

You can define "endianness" at runtime as follows:

 #define LITTLE_ENDIAN 0 #define BIG_ENDIAN 1 int endian() { int i = 1; char *p = (char *)&i; if (p[0] == 1) return LITTLE_ENDIAN; else return BIG_ENDIAN; } 

... and act accordingly.

I borrowed a code snippet from here: http://www.ibm.com/developerworks/aix/library/au-endianc/index.html?ca=drs- , where there is also an excellent discussion of these issues.

hth -

Perry

+1
source

Source: https://habr.com/ru/post/1347826/


All Articles