Re: [Dev-C++] Shift operators portability
Open Source C & C++ IDE for Windows
Brought to you by:
claplace
|
From: Per W. <pw...@ia...> - 2003-09-23 21:07:30
|
The read_int() and write_int() functions are the standard way of writing
portable files or data streams etc. Since the file is normalized, it
doesn't matter what machine created it. Obviously, such a file should be
binary so it doesn't contain any newline translations.
One other method often used, is to use htonl(), htons(), ntohl(), ntohs()
to convert between host and network byte order.
In this case, the network byte order is most significant byte first
(lowest address) and it is then possible to write the result of a htons()
or htonl() and write directly:
uint32_t n =3D htonl(my_long);
write(&n,1,sizeof(uint32_t),f);
/Per W
On Tue, 23 Sep 2003, OROSZI Bal=E1zs wrote:
> Hi!
>
> As I see a lot of things are told about this shifting stuff, so I think
> I might also add something.
> Bit shifting/or-ing/and-ing and so on, are VERY VERY useful things.
> There might be times, when you need to use all 8 bits of a byte. For
> example, when you have a big-big table (2D), and all you want to know,
> whether one cell is alive or not - 1 byte to store each cell is too much
> waste. Use 1 byte to store 8 cells, and use bit-masking to get the bits.
> But this is only one example, there are hundreds.
>
> And I also want to add something for the endiannes-stuff. Lets consider,
> that you wan't to save a 4 byte integer in binary form into a file
> (binary - save the int in 4 bytes to a file). You will probably begin
> pondering about endianness, and write specific loading code for big- and
> little-endian machines. However, there is a tricky solution to evade the
> endiannes problem, and saving an integer in binary form and loading it
> back will work on both big and little endian machines with the exact
> same code. Here it is (let's consider, that int is 4 bytes, but you may
> rewrite it to uint32_t to be sure):
>
> void write_int(FILE *outfile, int i)
> {
> putc( i&0x000000ff,outfile); /* Write the last byte */
> putc((i&0x0000ff00)>>8,outfile); /* etc. */
> putc((i&0x00ff0000)>>16,outfile);
> putc((i&0xff000000)>>24,outfile);
> }
>
> int read_int(FILE *infile)
> {
> int i=3D0;
>
> i |=3D ( (int)getc(infile)); /* Read the last byte: 0x000000xx */
> i |=3D (((int)getc(infile))<<8); /* Next: 0x000000xx<<8 =3D 0x0000xx0=
0 */
> i |=3D (((int)getc(infile))<<16); /* etc. */
> i |=3D (((int)getc(infile))<<24);
> return i;
> }
>
> The code above doesn't use any explicit conversion from int to char*,
> which is - lets say it - ugly. It works, because bit-shifting is
> "endian-free" i.e. it doesn't depend on endiannes. It works on both
> types of machines. As you can see, it uses the so-blessed shifting and
> bit-masking operators to ahcieve this goal.
>
> I hope I could add something useful.
> --
> Greetings,
> Bal=E1zs
>
>
>
>
> -------------------------------------------------------
> This sf.net email is sponsored by:ThinkGeek
> Welcome to geek heaven.
> http://thinkgeek.com/sf
> _______________________________________________
> Dev-cpp-users mailing list
> Dev...@li...
> TO UNSUBSCRIBE: http://www23.brinkster.com/noicys/devcpp/ub.htm
> https://lists.sourceforge.net/lists/listinfo/dev-cpp-users
>
|