Topic: shift oft signed ints
Author: Mathias Gaunard <loufoque@gmail.com>
Date: Mon, 20 Aug 2007 09:18:07 CST Raw View
On Aug 14, 9:05 pm, James Kanze <james.ka...@gmail.com> wrote:
> On Aug 13, 5:04 pm, Mathias Gaunard <loufo...@gmail.com> wrote:
>
> > On 13 ao t, 14:24, is...@inter.net (Olaf) wrote:
> > > int main()
> > > {
> > > int16_t i = - 36;
> > > int16_t r_sl = (i<<1);
> > > int16_t r_sr = (i>>1);
> > To begin with, I think the C++ standard allows bytes to be bigger than
> > 8 bits.
>
> The C standard requires int16_t to have exactly 16 bits, and use
> 2's complement. So does the current draft of the C++ standard.
That's quite irrelevant to what I said. Of course I already knew that.
My point was that 16 bits could be on a single byte. And shifting
works on bytes.
With such a byte size, shifting a number right once, for example,
would result in zero.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: kuyper <kuyper@wizard.net>
Date: Mon, 20 Aug 2007 13:02:34 CST Raw View
Mathias Gaunard wrote:
> On Aug 14, 9:05 pm, James Kanze <james.ka...@gmail.com> wrote:
> > On Aug 13, 5:04 pm, Mathias Gaunard <loufo...@gmail.com> wrote:
> >
> > > On 13 ao t, 14:24, is...@inter.net (Olaf) wrote:
> > > > int main()
> > > > {
> > > > int16_t i = - 36;
> > > > int16_t r_sl = (i<<1);
> > > > int16_t r_sr = (i>>1);
> > > To begin with, I think the C++ standard allows bytes to be bigger than
> > > 8 bits.
> >
> > The C standard requires int16_t to have exactly 16 bits, and use
> > 2's complement. So does the current draft of the C++ standard.
>
> That's quite irrelevant to what I said. Of course I already knew that.
> My point was that 16 bits could be on a single byte. And shifting
> works on bytes.
> With such a byte size, shifting a number right once, for example,
> would result in zero.
Why would shifting it right by one bit have that effect?
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: Mathias Gaunard <loufoque@gmail.com>
Date: Tue, 21 Aug 2007 10:39:18 CST Raw View
On Aug 20, 9:02 pm, kuyper <kuy...@wizard.net> wrote:
> Why would shifting it right by one bit have that effect?
Because for some reason I was imagining we were shifting bytes and not
bits.
Anyway, excuse my foolishness.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: is.er@inter.net (Olaf)
Date: Mon, 13 Aug 2007 12:24:56 GMT Raw View
Hello,
is there a guarantee by the standard that the following code will result
into a correct result always?:
#include <iostream>
#include <stdint.h>
using namespace std;
int main()
{
int16_t i = - 36;
int16_t r_sl = (i<<1);
int16_t r_sr = (i>>1);
cout << "i = "
<< i << ", (" << i << " << 1) = " << r_sl << endl;
cout << "i = "
<< i << ", (" << i << " >> 1) = " << r_sr << endl;
}
$ ./sign_shift.exe
i = -36, (-36 << 1) = -72
i = -36, (-36 >> 1) = -18
Due to the representation as 2er complement I would expect that the sign
bit gets lost by performing a left shift or even wrong result on right
shift.
Thanks,
Olaf
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: James Kanze <james.kanze@gmail.com>
Date: Mon, 13 Aug 2007 09:04:09 CST Raw View
On Aug 13, 2:24 pm, is...@inter.net (Olaf) wrote:
> is there a guarantee by the standard that the following code will result
> into a correct result always?:
> #include <iostream>
> #include <stdint.h>
> using namespace std;
> int main()
> {
> int16_t i = - 36;
> int16_t r_sl = (i<<1);
> int16_t r_sr = (i>>1);
> cout << "i = "
> << i << ", (" << i << " << 1) = " << r_sl << endl;
> cout << "i = "
> << i << ", (" << i << " >> 1) = " << r_sr << endl;
> }
> $ ./sign_shift.exe
> i = -36, (-36 << 1) = -72
> i = -36, (-36 >> 1) = -18
> Due to the representation as 2er complement I would expect that the sign
> bit gets lost by performing a left shift or even wrong result on right
> shift.
You don't define what you mean by "a correct result" here, but
in general, the results of right shifting a negative number is
implementation defined.
--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orient e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S mard, 78210 St.-Cyr-l' cole, France, +33 (0)1 30 23 00 34
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: Mathias Gaunard <loufoque@gmail.com>
Date: Mon, 13 Aug 2007 09:04:01 CST Raw View
On 13 ao t, 14:24, is...@inter.net (Olaf) wrote:
> int main()
> {
> int16_t i = - 36;
> int16_t r_sl = (i<<1);
> int16_t r_sr = (i>>1);
To begin with, I think the C++ standard allows bytes to be bigger than
8 bits.
So the result of those operations is quite unspecified.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: "Jim Langston" <tazmaster@rocketmail.com>
Date: Mon, 13 Aug 2007 20:58:41 CST Raw View
"James Kanze" <james.kanze@gmail.com> wrote in message
news:1187011772.329425.226010@57g2000hsv.googlegroups.com...
> On Aug 13, 2:24 pm, is...@inter.net (Olaf) wrote:
>> is there a guarantee by the standard that the following code will result
>> into a correct result always?:
>
>> #include <iostream>
>> #include <stdint.h>
>
>> using namespace std;
>
>> int main()
>> {
>> int16_t i = - 36;
>> int16_t r_sl = (i<<1);
>> int16_t r_sr = (i>>1);
>
>> cout << "i = "
>> << i << ", (" << i << " << 1) = " << r_sl << endl;
>> cout << "i = "
>> << i << ", (" << i << " >> 1) = " << r_sr << endl;
>> }
>
>> $ ./sign_shift.exe
>> i = -36, (-36 << 1) = -72
>> i = -36, (-36 >> 1) = -18
>
>> Due to the representation as 2er complement I would expect that the sign
>> bit gets lost by performing a left shift or even wrong result on right
>> shift.
>
> You don't define what you mean by "a correct result" here, but
> in general, the results of right shifting a negative number is
> implementation defined.
Just to be a little more clear, implementation defined means the out put
from two different compilers may be different.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: James Kanze <james.kanze@gmail.com>
Date: Tue, 14 Aug 2007 10:30:00 CST Raw View
On Aug 14, 4:58 am, "Jim Langston" <tazmas...@rocketmail.com> wrote:
> "James Kanze" <james.ka...@gmail.com> wrote in message
> news:1187011772.329425.226010@57g2000hsv.googlegroups.com...
> > On Aug 13, 2:24 pm, is...@inter.net (Olaf) wrote:
> >> is there a guarantee by the standard that the following code will result
> >> into a correct result always?:
> >> #include <iostream>
> >> #include <stdint.h>
> >> using namespace std;
> >> int main()
> >> {
> >> int16_t i = - 36;
> >> int16_t r_sl = (i<<1);
> >> int16_t r_sr = (i>>1);
> >> cout << "i = "
> >> << i << ", (" << i << " << 1) = " << r_sl << endl;
> >> cout << "i = "
> >> << i << ", (" << i << " >> 1) = " << r_sr << endl;
> >> }
> >> $ ./sign_shift.exe
> >> i = -36, (-36 << 1) = -72
> >> i = -36, (-36 >> 1) = -18
> >> Due to the representation as 2er complement I would expect that the sign
> >> bit gets lost by performing a left shift or even wrong result on right
> >> shift.
> > You don't define what you mean by "a correct result" here, but
> > in general, the results of right shifting a negative number is
> > implementation defined.
> Just to be a little more clear, implementation defined means
> the output from two different compilers may be different.
And that the behavior must be one of a small set of allowed
behaviors (here: it's implementation defined whether the bit
shifted in at the top is the sign bit, or always 0), and that
the compiler must document which one it chooses (but lot's of
luck finding that documentation).
But I expect that most posters here are already aware of that
(except that most compiler vendors seem to have missed the "must
be documented" requirement).
--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orient e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S mard, 78210 St.-Cyr-l' cole, France, +33 (0)1 30 23 00 34
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: James Kanze <james.kanze@gmail.com>
Date: Tue, 14 Aug 2007 13:05:58 CST Raw View
On Aug 13, 5:04 pm, Mathias Gaunard <loufo...@gmail.com> wrote:
> On 13 ao t, 14:24, is...@inter.net (Olaf) wrote:
> > int main()
> > {
> > int16_t i = - 36;
> > int16_t r_sl = (i<<1);
> > int16_t r_sr = (i>>1);
> To begin with, I think the C++ standard allows bytes to be bigger than
> 8 bits.
The C standard requires int16_t to have exactly 16 bits, and use
2's complement. So does the current draft of the C++ standard.
> So the result of those operations is quite unspecified.
They are implementation defined, not unspecified. First, i is
converted to an int (the size of which is implementation
defined, but guaranteed to be large enough to hold an int16_t
anywhere int16_t exists, so the conversion is value preserving).
Then that int is shifted. For the left shift, the results are
the value of that int, interpreted as a bit pattern, shifted
left, with zeros inserted at the right. If the initial value
was -36, this is guaranteed to result in a value that is
representable in an int16_t, so the resulting assignment is well
defined as well (and unless we're in the extremely unrealistic
case where the machine uses 2's complement for 16 bit ints, but
some other representation for int, the value is well defined as
well). For the right shift, it's a bit more delicate; if the
implementation uses a sign preserving shift, the results should
still be representable in an int16_t, and there should be no
problem. If the implementation inserts 0's, however, the
previously negative -36 will have become positive, and possibly
a very big positive number, which isn't representable in an
int16_t. The behavior in this case is, again, implementation
defined (not unspecified), and the operation may result in an
implementation defined signal (at least according to the C
standard; the C++ standard just says that the results are
implementation defined, without any restrictions on what those
results might be).
--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orient e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S mard, 78210 St.-Cyr-l' cole, France, +33 (0)1 30 23 00 34
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]