# Shift right (FB SHR)

## Recommended Posts

In my application I shift right 13 bits in a numeric value (for example 8000h). FB SHR puts FFFCh on its output.

Is it right?

##### Share on other sites

Hi, i would use some single scan conditional element, like a -|P|- contact before the shift block, or it will run on every scan.

If you would like to see what is happening with the bits, i would recommend using the memory field and setting it up like in this image. You can watch the bits shifting right. If the MSB is a 0, it will shift in a 0, and if it is a 1, it will shift in a 1.

I have attached an example as well.

v570 shift right example.vlp

##### Share on other sites

According windows calculator the result is absolutely correct.

##### Share on other sites

According windows calculator the result is absolutely correct.

I think the result must be 0000000000000100 but not 1111111111111100.

##### Share on other sites

If you would like to see what is happening with the bits, i would recommend using the memory field and setting it up like in this image. You can watch the bits shifting right. If the MSB is a 0, it will shift in a 0, and if it is a 1, it will shift in a 1.

8000h has MSB=1. So MI will be filled by 1 while shifting. Am I right?

Then how can I fill MI by 0 while shifting to get 0000000000000100?

##### Share on other sites

I think the result must be 0000000000000100 but not 1111111111111100.

Probably what is happening is since the MI is treated as a signed number, and you put 8000 hex in, it is treating it still like a negative number.

The range of an MI is -32768 to +32767

8000h equals 32768

So you are probably shifting in an overflow or sign bit somehow.

Whatever the case may be, technically 8000h is out of range for an MI. If you try to enter 32768 in decimal into an MI it will not let you.

If you need all 16bits, possibly consider using an ML or a DW instead.

D

##### Share on other sites

Hi,

You can achieve the result you want by dividing the original value by 8192 (2^13)

It seems that the Shift Right does not preserve sign.

##### Share on other sites

Hi,

You can achieve the result you want by dividing the original value by 8192 (2^13)

It seems that the Shift Right does not preserve sign.

Hi.

Dividing by 8192 gives the same result. I see the solution. I must analyze the result and multiply by -1 if MSB=1.

But seems to me that it is PLC's bug. There must be possible to shift bits from any position.

##### Share on other sites

To get a desired result, store 8000h into Memory Long, then RSH.

##### Share on other sites

Hi.

Dividing by 8192 gives the same result. I see the solution. I must analyze the result and multiply by -1 if MSB=1.

But seems to me that it is PLC's bug. There must be possible to shift bits from any position.

Hi, I now understand what you want... I thought that Visilogic and the PLC does not preserve the sign in Shift Right...

Actually, Visilogic is acting as it should... Shift right is like dividing by 2.

Lets start with the fact that 8000h is not equal 32768. 8000h (of 0x8000 as some people write) is -32786, so the result of dividing it by 8192 gives the result -4, which is 0xFFFC

Shift right would gave the same result.

So as some people proposed, you need to put the number 0x8000 to a ML, so the MSB won't be 1.

##### Share on other sites

It's not a bug...

The sign is not god sent magic. In signed operands (MI, XI, ML and XL in Unitronics OPLC) the sign is the MSB). Whe the sign is <->, this bit is 1. When shifting bits, this bit is moving left or right. This is quite natural.

##### Share on other sites

So as some people proposed, you need to put the number 0x8000 to a ML, so the MSB won't be 1.

I understand this solution. I think my solution (multipliing by -1) isn't worse.

And I suppose the fact (MSB must be 0 if you shift right) must be noticed in help-files.

##### Share on other sites

Whe the sign is <->, this bit is 1. When shifting bits, this bit is moving left or right. This is quite natural.

I understand that this bit means the sign.

It isn't moving left or right like other bits.

One more example is below.

8000h = 1000000000000000

E000h = 1110000000000000

But if I shift right 2 positions the result must be 2000h = 0010000000000000.

##### Share on other sites

Perhaps also there should be some changing of the wording in the help regarding the MI's.

From the help file.........

"Memory Integers are 16-bit integer operands that may be signed or unsigned. The range of an MI is -32768 to +32767."

I think it may be a misnomer to state that the MI can be treated as an unsigned integer. If it could be unsigned, it would indicate that it would have a range of (0 to +65536). Stating that you can treat it as unsigned gives the false impression that you could alter how the MSB is treated.

## Create an account

Register a new account

×