Thread: [Dev-C++] Shift operators portability
Open Source C & C++ IDE for Windows
Brought to you by:
claplace
|
From: David M. <ci...@ya...> - 2003-09-23 01:14:57
|
Hi there. Are the shift operators ( << and >> ) portable? i.e. Does x << 1 have the same effect as multiplying by 2 ? and Does x >> 1 have the same effect as dividing by 2? On both big and little endian order machines? also is there any wraparound? i.e. in a shift the bits that are pushed out of the data structure placed at the back-end of the data structure (on the other side of where they were pushed out)? Thanks in Advance David McKen --------------------------------- Do you Yahoo!? Yahoo! SiteBuilder - Free, easy-to-use web site design software |
|
From: Michael D. S. <for...@hi...> - 2003-09-23 04:37:54
|
No wraparound, they drop off the end, at least on any machine I've ever
been familiar with.
I thought I would try, see how it works on this machine and got nothing. No
compiler error, and no change in the int.
Anyone know why this produces nothing (16) every time? And I tried other
numbers, in both positions, as well. Even tried turning it around -- Same
thing, nothing, every time. It seems there should be some effect, or an
error..
I have an AMD processor and no idea if it's big or little endian.
#include<iostream.h>
#include<stdlib.h>
#include<fstream.h>
int main()
{
int count = 16;
count >> 2;
cout << "count = " << count << "\n";
2 << count;
cout << "count = " << count << "\n";
system ("pause");
return 0;
}
At 08:14 PM 9/22/03, you wrote:
>Hi there.
>
>Are the shift operators ( << and >> ) portable?
>i.e.
>Does x << 1 have the same effect as multiplying by 2 ?
>and
>Does x >> 1 have the same effect as dividing by 2?
>On both big and little endian order machines?
>
>also is there any wraparound?
>i.e. in a shift the bits that are pushed out of the data structure placed
>at the back-end of the data structure (on the other side of where they
>were pushed out)?
>
>Thanks in Advance
>David McKen
>
>
>Do you Yahoo!?
><http://us.rd.yahoo.com/evt=10469/*http://sitebuilder.yahoo.com>Yahoo!
>SiteBuilder - Free, easy-to-use web site design software
|
|
From: Per W. <pw...@ia...> - 2003-09-23 06:07:04
|
They don't wrap around since they are shift operators and not rotate
operators.
Some care should be used with negative numbers since most machines are
using two-complement numbers which high bit specifies if number is
negative. By shifting that bit, you definitely don't get mult/div with
two.
As long as you don't try to load only a part of a number and perform a
shift on, big or little endian doesn't matter. The endianness is only how
the number is stored in memory. When loaded into the processor, it is just
a number.
Big or little endian doesn't matter - unless a number is processed
The sample program below doesn't work becase it isn't assigning the result
of the shifts.
count <<= 1;
count >>= 1;
or
count = count << 1;
count = count >> 1;
/Per W
On Mon, 22 Sep 2003, Michael D. Smith wrote:
>
> No wraparound, they drop off the end, at least on any machine I've ever
> been familiar with.
>
> I thought I would try, see how it works on this machine and got nothing. No
> compiler error, and no change in the int.
>
> Anyone know why this produces nothing (16) every time? And I tried other
> numbers, in both positions, as well. Even tried turning it around -- Same
> thing, nothing, every time. It seems there should be some effect, or an
> error..
>
> I have an AMD processor and no idea if it's big or little endian.
>
>
>
> #include<iostream.h>
> #include<stdlib.h>
> #include<fstream.h>
>
> int main()
> {
> int count = 16;
>
> count >> 2;
> cout << "count = " << count << "\n";
>
> 2 << count;
> cout << "count = " << count << "\n";
>
> system ("pause");
> return 0;
> }
>
>
> At 08:14 PM 9/22/03, you wrote:
> >Hi there.
> >
> >Are the shift operators ( << and >> ) portable?
> >i.e.
> >Does x << 1 have the same effect as multiplying by 2 ?
> >and
> >Does x >> 1 have the same effect as dividing by 2?
> >On both big and little endian order machines?
> >
> >also is there any wraparound?
> >i.e. in a shift the bits that are pushed out of the data structure placed
> >at the back-end of the data structure (on the other side of where they
> >were pushed out)?
> >
> >Thanks in Advance
> >David McKen
> >
> >
> >Do you Yahoo!?
> ><http://us.rd.yahoo.com/evt=10469/*http://sitebuilder.yahoo.com>Yahoo!
> >SiteBuilder - Free, easy-to-use web site design software
>
>
>
> -------------------------------------------------------
> 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
>
|
|
From: Neszt T. <ne...@ss...> - 2003-09-23 11:06:02
|
> I have an AMD processor and no idea if it's big or little endian.
main() {
int x = 1;
if (*(char *)&x == 1) {
printf("little-endian\n");
} else {
printf("big-endian\n");
}
}
Regards,
Neszt Tibor
|
|
From: Per W. <pw...@ia...> - 2003-09-23 11:15:35
|
The AMD is same as Intel, or it wouldn't run x86 code.
/Per W
On Tue, 23 Sep 2003, Neszt Tibor wrote:
> > I have an AMD processor and no idea if it's big or little endian.
>
> main() {
> int x = 1;
> if (*(char *)&x == 1) {
> printf("little-endian\n");
> } else {
> printf("big-endian\n");
> }
> }
>
>
> Regards,
> Neszt Tibor
>
>
>
> -------------------------------------------------------
> 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
>
|
|
From: Michael D. S. <for...@hi...> - 2003-09-23 14:56:23
|
Prints little endian. I have no idea why :)
ms
At 06:03 AM 9/23/03, you wrote:
> > I have an AMD processor and no idea if it's big or little endian.
>
>main() {
> int x = 1;
> if (*(char *)&x == 1) {
> printf("little-endian\n");
> } else {
> printf("big-endian\n");
> }
>}
>
>
>Regards,
> Neszt Tibor
|
|
From: Per W. <pw...@ia...> - 2003-09-23 15:26:50
|
The program picks up the first byte of the integer - as stored in memory.
If it is 1, it's the side where the "little" part of the integer is
stored. If it is 0, it's the side where the "large" part is stored.
Intel, AMD store low byte of integer first, so it is expected that at the
first byte of the address of the integer, the value 1 should be stored.
The other three bytes of the integer will all be zero.
/Per W
On Tue, 23 Sep 2003, Michael D. Smith wrote:
>
> Prints little endian. I have no idea why :)
>
> ms
>
>
> At 06:03 AM 9/23/03, you wrote:
> > > I have an AMD processor and no idea if it's big or little endian.
> >
> >main() {
> > int x = 1;
> > if (*(char *)&x == 1) {
> > printf("little-endian\n");
> > } else {
> > printf("big-endian\n");
> > }
> >}
> >
> >
> >Regards,
> > Neszt Tibor
>
>
>
> -------------------------------------------------------
> 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
>
|
|
From: <or...@vp...> - 2003-09-23 19:26:20
|
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=0;
i |= ( (int)getc(infile)); /* Read the last byte: 0x000000xx */
i |= (((int)getc(infile))<<8); /* Next: 0x000000xx<<8 = 0x0000xx00 */
i |= (((int)getc(infile))<<16); /* etc. */
i |= (((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ázs
|
|
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
>
|