Easy question: How do I specify "or" in a script?

Started by poc301, Thu 10/12/2009 15:20:30

Previous topic - Next topic

poc301

I need to do "If x==1 OR X==3" then do something, but I can't find out what the script equivalent to OR is...  I know AND is && but the manual and the forums don't return anything useful when you do a search for "OR"  because it is a term in and of itself :(

Help!

Thanks,

Bill

Matti

#1
||  ;)


Edit: Under Scripting > Script language keywords > operators is a list of all possible operators.

Edit 2: My first edit got beaten by monkey! What a competition  ;)

monkey0506

The logical OR operator is ||. Two of the vertical bars above the return key. ;)

And I know I got beaten to the punch, but Script language keywords is the page you're looking for, under Operators.

Quote from: The manual
 !    NOT                        if (!a) 
 *    Multiply                   a = b * c;
 /    Divide                     a = b / c;
 %    Remainder                  a = b % c;
 +    Add                        a = b + c;
 -    Subtract                   a = b - c;
 <<   Bitwise Left Shift         a = b << c;
      (advanced users only) 
 >>   Bitwise Right Shift        a = b >> c;
      (advanced users only) 
 &    Bitwise AND                a = b & c;
      (advanced users only) 
 |    Bitwise OR                 a = b | c;
      (advanced users only) 
 ^    Bitwise XOR                a = b ^ c;
      (advanced users only) 
 ==   Is equal to                if (a == b)
 !=   Is not equal to            if (a != b)
 >    Is greater than            if (a > b)
 <    Is less than               if (a < b)
 >=   Is greater than or equal   if (a >= b)
 <=   Is less than or equal      if (a <= b)
 &&   Logical AND                if (a && b)
 ||   Logical OR                 if (a || b)

Ryan Timothy B

#3
I'll have to admit, over 2 years ago when I first started with AGS I also had a problem for about an hour finding out what OR was.  Finding the keywords from the manual: Script Language Keywords or Operators, took me quite a while.  Mostly because I am not a programmer and didn't know that they are called operators.

I believe for me to find out what OR was, I had actually done a search in the technical threads for a sample of script that had an OR operator.

That's the truth folks. lol  :-\

edit: Also, there isn't anywhere in the manual that explains what exactly the bitwise operators do:
<<    >>     &     |     ^
I've always been curious.  Are there any agswiki documents or anything on it?

monkey0506

#4
The bitwise operators perform bitwise operations. :P That is, they actually work directly on the binary bits of the given value. To understand them you must therefore understand the way binary works.

Binary is a number system like the decimal or hexadecimal systems, except instead of having 10 or 16 possible values per digit, binary only has two. That is:

Decimal digit values: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
Hexadecimal digit values: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F
Binary digit values: 0, 1

Once the highest possible value for that digit is reached, to increase the value you reset that digit back to 0, and increase the next digit to the next highest value. This is very simple in binary since there are only two possible values. Each digit in binary represents a power of two. The right-most digit is 2^0 (that is, it's 1) and each digit to the left represents the next highest power of 2. So counting in binary looks like this:

Code: ags
0 (dec) = 2^0 * 0 = 0 (bin)
1 (dec) = 2^0 * 1 = 1 (bin)
2 (dec) = 2^1 * 1 + 2^0 * 0 = 10 (bin)
3 (dec) = 2^1 * 1 + 2^0 * 1 = 11 (bin)
4 (dec) = 2^2 * 1 + 2^1 * 0 + 2^0 * 0 = 100 (bin)


For more on binary numbers...Google. :P

Now let's take a look at those bitwise operators. Just for clarity's sake, a binary digit is also called a bit. ;)

<< (Left shift)
This operator shifts all the bits in the given value to the left by a given number of places. So:

Code: ags
100 << 1 = 1000
100 << 2 = 10000
100 << 3 = 100000


Etc. This is equivalent to multiplying X * 2^Y where X is the number on the left side of the operator and Y is the number on the right side. In decimal form this would look like:

Code: ags
4 << 1 = 4 * 2^1 = 4 * 2 = 8
4 << 2 = 4 * 2^2 = 4 * 4 = 16
4 << 3 = 4 * 2^3 = 4 * 8 = 32


>> (Right shift)
This operator does the reverse operation of the << left shift operator, and shifts all the binary digits to the right by a given value:

Code: ags
100 >> 1 = 10
100 >> 2 = 1
100 >> 3 = 0


This is the same as X / 2^Y (rounded down). In decimal this looks like:

Code: ags
4 >> 1 = 4 / 2^1 = 4 / 2 = 2
4 >> 2 = 4 / 2^2 = 4 / 4 = 1
4 >> 3 = 4 / 2^3 = 4 / 8 = 0


& (bitwise AND)
This works in a similar way to the logical AND operator && except instead of comparing boolean values it compares bit values. The result of a bitwise AND is such that the bits which are the SAME between the two given values are represented as 1 and all other bits are represented as 0:

Code: ags
0 & 1 = 0
1 & 1 = 1
101 & 1111 = 101 // only the bits which are the same are set in the resulting value
11001100 & 110011 = 0


This does not have a valid mathematical equivalent and is therefore meaningless in terms of decimal values. This operation is commonly used for what are known as bit masks which is a way of feeding several bits of data through a single function parameter. For an example, see the next section.

| (bitwise OR)
Again, this operator works similarly to the logical equivalent OR operator ||. This time however instead of making sure that the bits in the two values are the SAME, it checks whether EITHER value has its bit set to 1:

Code: ags
0 | 1 = 1
1 | 1 = 1
101 | 1111 = 1111
11001100 | 110011 = 11111111


Just as with the bitwise AND, the bitwise OR is also used commonly in bit masks. For example, you might use a bit mask as a way of detecting errors in a program.

Code: ags
#define PARAM1_ERROR 1
#define PARAM2_ERROR 2
#define PARAM3_ERROR 4 // note each is an increasing power of 2 so it has a totally unique bit value
#define PARAM4_ERROR 8

function error(int flags) {
  // by using the bitwise AND we compare the given flags against our first possible error
  // if this flag was not set then the AND operation will return 0 (evaluated as false)
  if (flags & PARAM1_ERROR) Display("There was an error with PARAM1. Please consult the documentation.");
  if (flags & PARAM2_ERROR) Display("There was an error with PARAM2. Please consult the documentation.");
  if (flags & PARAM3_ERROR) Display("There was an error with PARAM3. Please consult the documentation.");
  if (flags & PARAM4_ERROR) Display("There was an error with PARAM4. Please consult the documentation.");
}

function my_func(int param1, int param2, int param3, int param4) {
  int flags = 0; // we'll use this to check for errors
  if (param1 < 0) flags = flags | PARAM1_ERROR; // by using the OR operator we add the PARAM1_ERROR without disrupting the existing flags
  if (param2 > 289) flags = flags | PARAM2_ERROR;
  if ((param3 < 62) || (param3 > 98)) flags = flags | PARAM3_ERROR; // be sure not to confuse the binary and bitwise operators ;)
  if (param4 < 2000) flags = flags | PARAM4_ERROR;
  if (flags) { // if any of the errors were set this is non-zero and evaluates as true
    error(flags); // tell the user about the errors
    return; // abort operation
  }
  // otherwise continue on
}


Not the world's greatest example but honestly I've never had a need to use a bitmask, so. :P That said, it's important to note that each of the masks (that is, the values defined before the functions) must have completely unique binary representations or they can't be properly combined this way (they would affect the binary values of each other if combined). Also of course make sure to take care not to confuse the binary (bitwise) and logical operators.

^ (bitwise XOR)
This is a fun little operator that will actually compare the bits of the given values and the resulting bit will be 1 only if the two bits are different; if they are the same it will give 0:

Code: ags
0 ^ 1 = 1 // bits are different, gives 1
1 ^ 1 = 0 // bits are the same, gives 0
101 ^ 1111 = 1010
11001100 ^ 110011 = 11111111


What's the practical use of this you ask? Frankly, I just don't know. := Actually, I do know that the XOR operator is commonly used in encryption algorithms, but outside of that field I'm unaware of other uses for this.

! (NOT operator)

While we're on the topic of bitwise operators it's worth noting the effect that the ! operator has on the bits in a value. Essentially this operator just switches each bit to it's opposite value:

Code: ags
!0 = 1
!1 = 0
!100110 = 11001


As for this one, I don't really know any practical usage other than the most commonplace one which is:

Code: ags
!false = true
!true = false


Since false has (in AGS at least) the binary equivalent of 0 and true the binary equivalent of 1. ;)

And that's enough for one day. Again if you're interested in learning more, Google. 8)

Ryan Timothy B

Thanks for the descriptions.  Seems a bit over my head since I haven't any reason at all to work with binary/hex/decimal.
I had a feeling bitwise meant it worked with those, just wasn't sure.  What purposes would someone using AGS need these for?  My guess, as you had stated before, would be encryption of sorts, or some type of saving game information possibly?

monkey0506

#6
About the only time I can think of that I've personally used the bitwise operators is in file encryption as I said. And as displayed above you could of course use them for a bitmask, but I've never had cause to use one of those.

So basically I understand what it does, but it's not something with a wide range of practical uses. ;)

Oh and to clarify the bitwise operators don't strictly have anything to do with the hexadecimal system. I was just using that for comparative purposes since it is one of the most common numeral systems used in programming (decimal (base 10), hexadecimal (base 16), octal (base 8), and binary (base 2)). And you say you've never had any reason to use the decimal system? Ever? Honestly? Wow...imagine a life without numbers... ::)




In other news, I just tested an idea I had and it's possible to define verbose versions of these operators such as:

Code: ags
#define and      &&
#define or       ||
#define not       !
#define equals   ==
#define notequal !=


And if you prefer you can even take it a step further and do this (in recent versions of AGS):

Code: ags
managed struct      and {};
managed struct       or {};
managed struct      not {};
managed struct      xor {};
managed struct   equals {};
managed struct notequal {};

#define and      && // $AUTOCOMPLETEIGNORE$
#define or       || // $AUTOCOMPLETEIGNORE$
#define not       ! // $AUTOCOMPLETEIGNORE$
#define equals   == // $AUTOCOMPLETEIGNORE$
#define notequal != // $AUTOCOMPLETEIGNORE$


The purpose of this being that in the most recent versions struct names are highlighted in a light blue color, so this could help visually distinguish them. There's no real purpose behind them being declared as managed except to indicate that we're never going to use them. := The struct definition gets hidden by the #define.

SMF spam blocked by CleanTalk