Difference between revisions of "Right Shift"
Line 3: | Line 3: | ||
== Bitwise vs. Arithmetic == | == Bitwise vs. Arithmetic == | ||
There are two types of Right Shifts, that can be performed on an integer. They are: Bitwise and Arithmetic. LSL currently only supports Arithmetic. The difference between the two modes is how it fills the bits revealed. In bitwise mode, the revealed bits are always zero; in Arithmetic mode, it duplicates the old top bit to all the new bits. If you take the expression <code> | There are two types of Right Shifts, that can be performed on an integer. They are: Bitwise and Arithmetic. LSL currently only supports Arithmetic. The difference between the two modes is how it fills the bits revealed. In bitwise mode, the revealed bits are always zero; in Arithmetic mode, it duplicates the old top bit to all the new bits. If you take the expression <code>value >> count</code> where ''value'' is arithmetically shifted right ''count'' bits, then this is the same mathematically as doing <code>value / (2<sup>count</sup>)</code> or in LSL <code>value / [[llPow]](2.0, count)</code>. | ||
== How to do Bitwise Right Shifts in LSL == | == How to do Bitwise Right Shifts in LSL == | ||
Line 146: | Line 146: | ||
// this means it more closely resembles dividing by a | // this means it more closely resembles dividing by a | ||
// positive power of two then a bitwise right shift. | // positive power of two then a bitwise right shift. | ||
// To perform a bitwise right shift you need to be | // To perform a bitwise right shift you need to be clever | ||
integer rightShift(integer value, integer count) | integer rightShift(integer value, integer count) | ||
{ | { | ||
return (value >> count) & ~((~value) >> count); | return (value >> count) & ~((~value) >> count); | ||
//This works because only once side of the '&' operation | |||
//Has the sign bit extended by the arithmetic right shift | |||
//The purpose of flipping of the bits on the right side | |||
//ensures this, the subsequent '&' removes the extended | |||
//sign bits. | |||
}</lsl> | }</lsl> | ||
'''Example Usage:''' | '''Example Usage:''' |
Revision as of 03:30, 3 February 2008
LSL Portal | Functions | Events | Types | Operators | Constants | Flow Control | Script Library | Categorized Library | Tutorials |
Bitwise vs. Arithmetic
There are two types of Right Shifts, that can be performed on an integer. They are: Bitwise and Arithmetic. LSL currently only supports Arithmetic. The difference between the two modes is how it fills the bits revealed. In bitwise mode, the revealed bits are always zero; in Arithmetic mode, it duplicates the old top bit to all the new bits. If you take the expression value >> count
where value is arithmetically shifted right count bits, then this is the same mathematically as doing value / (2count)
or in LSL value / llPow(2.0, count)
.
How to do Bitwise Right Shifts in LSL
Since LSL does not have a bitwise right shift operator you have to do it yourself. There are two methods for doing this, each with it's advantages and disadvantages.
Method 1
<lsl>(value >> count) & ~((~value) >> count);</lsl> This method is good when count is dynamic. It works because all the bits that need to be turned on will be turned on both sides of the AND but on only one side will the arithmetic right shift cause the sign bit to be extended. The result of the and is a value that is always a bitwise right shift.
Method 2
<lsl>(value >> count) & mask;</lsl>
This method can only be used when count is a constant value. You use a constant mask to remove the extended sign bits. Example: (value >> 5) & 0x07FFFFFF
As you can see the top five bits have been turned off in the mask value, if you have trouble seeing that, you can just use the lookup table below.
|
|
|
Example Bitwise Right Shift Function
Here's a function to pass a signed 32 bit integer along with a value indicating how far to shift the bits. This method is primarily needed to shift bits for negative integers, as the regular bit shift operators work just fine for positive values.
<lsl>// the lsl right shift is an arithmetic right shift, // this means it more closely resembles dividing by a // positive power of two then a bitwise right shift. // To perform a bitwise right shift you need to be clever integer rightShift(integer value, integer count) {
return (value >> count) & ~((~value) >> count); //This works because only once side of the '&' operation //Has the sign bit extended by the arithmetic right shift //The purpose of flipping of the bits on the right side //ensures this, the subsequent '&' removes the extended //sign bits.
}</lsl> Example Usage: <lsl>default {
state_entry() {
// output should be 268435449 llSay(DEBUG_CHANNEL, (string)rightShift(-99, 4));
// before: 1111 1111 1111 1111 1111 1111 1001 1101 // after: 0000 1111 1111 1111 1111 1111 1111 1001 }
}</lsl>