f

#### Precision of C++ left/right shift operator..

```I am using this type of code to do right-shifting,

B = 3;
data1 = (data + (1 << (B-1))) >> B;

data1 seems incorrect when data = -4-8*i.. which means it
rounds -1.5 to -1 instead of -2.

On the positive side, 1.5 is rounded to 2, which ic correct.

For left-shift, it's simply as follows, no pitfalls, am I right?
data1 = data << B;

Thanks.

``` 0 7/31/2007 2:35:57 PM comp.lang.c++  49423 articles. 7 followers. 4 Replies 461 Views Similar Articles

[PageSpeed] 21

```G Iveco wrote:
> I am using this type of code to do right-shifting,
>
> B = 3;
> data1 = (data + (1 << (B-1))) >> B;
>
> data1 seems incorrect when data = -4-8*i.. which means it
> rounds -1.5 to -1 instead of -2.

Do you mean 'data' is declared as 'std::complex<int>' ?  If not,
how is it declared?  What's the type of 'data1'?

> On the positive side, 1.5 is rounded to 2, which ic correct.

Are you sure it's -1.5?  What if it's -1.49999999999?

> For left-shift, it's simply as follows, no pitfalls, am I right?
> data1 = data << B;

something we can just compile and run to see the behaviour).

V
--

``` 0 7/31/2007 3:11:42 PM
```"Victor Bazarov" <v.Abazarov@comAcast.net> wrote in message
news:f8njfd\$9o7\$1@news.datemas.de...
>G Iveco wrote:
>> I am using this type of code to do right-shifting,
>>
>> B = 3;
>> data1 = (data + (1 << (B-1))) >> B;
>>
>> data1 seems incorrect when data = -4-8*i.. which means it
>> rounds -1.5 to -1 instead of -2.
>
> Do you mean 'data' is declared as 'std::complex<int>' ?  If not,
> how is it declared?  What's the type of 'data1'?
>
>> On the positive side, 1.5 is rounded to 2, which ic correct.
>
> Are you sure it's -1.5?  What if it's -1.49999999999?
>

data and data1 are integer. Herer I use -1.5 to mean
-12.0/8 = -1.5, when right-shift, i was expecting -2.0 instead of -1.0..

same goes with 1.5, which means 12.0/8.0 and yield 2, as expected.

>> For left-shift, it's simply as follows, no pitfalls, am I right?
>> data1 = data << B;
>
> Please post the complete program (not all of your code, but
> something we can just compile and run to see the behaviour).
>
> V
> --
>

My complete source is simply a test of ideas.. as follows,

#include <cstdlib>
#include <iostream>

using namespace std;

int main(int argc, char *argv[])
{
int i, j;
int data;
double tmp;
int data0;
int data1;
int data2;
FILE *fp;

fp = fopen("./data.txt", "w");
int KK = -153;
int B = 5;
fprintf(fp, "\n\n\nRight shifting, division by 2^B");
for(i=0; i<300; i++) {
data = KK + i;
tmp = data * 1.0 / 32.0;
data0 = (int)tmp;
data1 = (data + (1 << (B-1))) >> B;
data2 = (data >> B) + ((data >> B-1) & 0x1);
fprintf(fp, "\ndata = %2d, tmp = %3.2f, data1 = %3d, data2 = %3d", data,
tmp, data1, data2);
}

fprintf(fp, "\n\n\nLeft shifting, multiply by 2^B");
for(i=0; i<300; i++) {
data = KK + i;
tmp = data * 8.0;
data0 = (int)tmp;
data1 = data << 3;
fprintf(fp, "\ndata = %2d, tmp = %3.2f, data1 = %3d, data0 = %3d", data,
tmp, data1, data0);
}
fclose(fp);

system("PAUSE");
return EXIT_SUCCESS;
}

``` 0 7/31/2007 3:21:46 PM
```G Iveco wrote:
> "Victor Bazarov" <v.Abazarov@comAcast.net> wrote in message
> news:f8njfd\$9o7\$1@news.datemas.de...
>> G Iveco wrote:
>>> I am using this type of code to do right-shifting,
>>>
>>> B = 3;
>>> data1 = (data + (1 << (B-1))) >> B;
>>>
>>> data1 seems incorrect when data = -4-8*i.. which means it

When you wrote 'data = -4-8*i' I took it that it's "complex" and
its real part is -4 and imaginary part is -8 (*i is the notation
to indicate the formula of a compex number 'a+b*i').  Since your
code didn't have any 'i', there was no other way for me to

>>> rounds -1.5 to -1 instead of -2.
>>
>> Do you mean 'data' is declared as 'std::complex<int>' ?  If not,
>> how is it declared?  What's the type of 'data1'?
>>
>>> On the positive side, 1.5 is rounded to 2, which ic correct.
>>
>> Are you sure it's -1.5?  What if it's -1.49999999999?
>>
>
>
> data and data1 are integer. Herer I use -1.5 to mean
> -12.0/8 = -1.5, when right-shift, i was expecting -2.0 instead of
> -1.0..

WHY???  Right shift does not round.  It discards the bits that are
shifted "out of existence".

I am guessing you're confused about shifting, division (those are
two separate operations), and how it is all done for integers versus
doubles.  You need to read up on integral operations.

V
--

``` 0 7/31/2007 3:36:32 PM
```On Jul 31, 5:36 pm, "Victor Bazarov" <v.Abaza...@comAcast.net> wrote:
> G Iveco wrote:
> > "Victor Bazarov" <v.Abaza...@comAcast.net> wrote in message
> > data and data1 are integer. Herer I use -1.5 to mean
> > -12.0/8 =3D -1.5, when right-shift, i was expecting -2.0 instead of
> > -1.0..

> WHY???  Right shift does not round.  It discards the bits that are
> shifted "out of existence".

Actually, right shift isn't well defined for negative numbers.
It's implementation defined whether it shifts in the sign or a
0=2E  And of course, the results (either way) depend on the
representation of negative numbers.

But whatever.  As you say, right shift deals with bits (or the
bit representation) and not the numeric values.  If you want to
deal with the numeric values, use the numeric operators.
(Except that in the current version of the C++ standard, which
way division rounds when the results are negative is
implementation defined as well.)

> I am guessing you're confused about shifting, division (those are
> two separate operations), and how it is all done for integers versus
> doubles.  You need to read up on integral operations.

Exactly.

--
James Kanze (Gabi Software)            email: james.kanze@gmail.com
Conseils en informatique orient=E9e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S=E9mard, 78210 St.-Cyr-l'=C9cole, France, +33 (0)1 30 23 00 34

``` 0 7/31/2007 7:31:00 PM