View previous topic :: View next topic |
Author |
Message |
kalo
Joined: 02 Dec 2003 Posts: 0
|
Logic shift with signed integer |
Posted: Thu Mar 04, 2004 7:21 am |
|
|
In my program I have only divisions by x�. I would like to shorten them by using right shift. Unfortunately the compiler shifts always 0 in. Is there any workaround instead of using a real division routine provided by CCS??? |
|
|
SteveS
Joined: 27 Oct 2003 Posts: 126
|
/2? |
Posted: Thu Mar 04, 2004 8:12 am |
|
|
I assume you mean /2?
If so try shift_right(). Beware the syntax - the address of the value must be sent, and it returns the 'remainder'; so use it like:
signed int8 value = -100;
int8 remainder;
remainder = shift_right( &value, 1, 1 );
will give value = -50;
Nice thing is it works for any number of bytes (int16, etc) and allows dividing by any power of 2.
- SteveS |
|
|
Neutone
Joined: 08 Sep 2003 Posts: 839 Location: Houston
|
Re: Logic shift with signed integer |
Posted: Thu Mar 04, 2004 8:30 am |
|
|
kalo wrote: | In my program I have only divisions by x�. I would like to shorten them by using right shift. Unfortunately the compiler shifts always 0 in. Is there any workaround instead of using a real division routine provided by CCS??? |
Read ths list file and you will note that the compiler does shifts for power of 2 division. No need to specify rotation. Just make the divisior a power of 2 that is a constant. |
|
|
SteveS
Joined: 27 Oct 2003 Posts: 126
|
|
Posted: Thu Mar 04, 2004 9:12 am |
|
|
Well, I thought the same and compiled code to check it.
s = -100;
s2 = s/2;
A call is made to DIVS88. I didn't look into that function - perhaps a test is made there.
I know I have seen it compile the shift in other programs I have done. That's why I cautioned someone the other day about trying to outsmart the compiler. It can make some pretty amazing optimizations.
Ahha - just tried something. An unsigned int will get the shift, signed int forces a call to DIVS88.
- SteveS |
|
|
Ttelmah Guest
|
|
Posted: Thu Mar 04, 2004 9:42 am |
|
|
SteveS wrote: | Well, I thought the same and compiled code to check it.
s = -100;
s2 = s/2;
A call is made to DIVS88. I didn't look into that function - perhaps a test is made there.
I know I have seen it compile the shift in other programs I have done. That's why I cautioned someone the other day about trying to outsmart the compiler. It can make some pretty amazing optimizations.
Ahha - just tried something. An unsigned int will get the shift, signed int forces a call to DIVS88.
- SteveS |
For a single shift I wouldn't worry about it. However the obvious 'solution', if wanting to do multiple shifts, is to test for the number being negative. If it is, set a flag, and change it's sign. Perform the rotations required, and then change the sign back if required.
Something like:
Code: |
signed int16 shiftsignedright(int16 val, int numbits){
int1 sign;
if (val & 0x8000l) {
sign=true;
val &=0x7FFFl;
}
else sign=false;
//Rotate as required here
shift_right(&val,2,numbits);
if (sign) val |=0x8000l;
return(val);
}
|
If you call this with a signed int16 number, this will be handed to the routine as an unsigned number (but with the sign bit still there). This is then tested, and removed if needed. The word is then rotated the number of bits specified, and the sign bit put back.
I think it ought to work....
Best Wishes |
|
|
|