kent logo

CO538 Anonymous Questions and Answers Keyword Index

This page provides a keyword index to questions and answers. Clicking on a keyword will take you to a page containing all questions and answers for that keyword, grouped by year.

To submit a question, use the anonymous questions page. You may find the keyword index and/or top-level index useful for locating past questions and answers.

Keyword reference for operators


Question 43 (2007):

Submission reference: IN1372

Hi, I'm changing the compute.speed function, but I had some trouble understanding the first one. Can you explain the code below because I can't find any explanations for the operators?

    IF i = 0 FOR 7
      range <= (robot.radius << i)
        speed := i


Answer 43:

The left and right shift operators, << and >>, are defined is slide 33 of basics and in section 2.2 ("Built-in Operators") of the occam-pi Quick Reference Wiki, which is linked from this module's web page.

See also Question 42 (2007), which observes that shifting the bit-pattern of a positive integer leftwards multiplies it by 2 for each bit shifted. So, expanding the above replicator fully (it's only 7 times) and replacing the shifts with equivalent multiplies, we get:

      range <= (robot.radius * 1)
        speed := 0
      range <= (robot.radius * 2)
        speed := 1
      range <= (robot.radius * 4)
        speed := 2
      range <= (robot.radius * 8)
        speed := 3
      range <= (robot.radius * 16)
        speed := 4
      range <= (robot.radius * 32)
        speed := 5
      range <= (robot.radius * 64)
        speed := 6

So long as range is not more than 64 times the radius of the robot, a speed will be assigned. In brain.0, that range is the minimum clear distance reported by the laser scanner. It sets the speed on a logarithmic scale, stopping it if it's bumped into something.

The greatest value the laser scanner can return is the length of its rays (see the variable laser.range in the main process). In that main process, laser.range is set to 32 times the robot.radius – so the above code is safe. If you change that ratio, you may need to protect that replicated IF – see Question 30 (2007).

Keywords: cylons , operators , shift

Question 42 (2007):

Submission reference: IN1369

What is the operator for raise-to-the-power? For example, 2^32 – what does occam-pi have for ^?

Answer 42:

occam-pi does not have a buiit-in raise-to-the-power operator. There is a built-in function for floating-point raise-to-the-power::


which returns x^y ... but I don't think you want that!

[By the way, the built-in adjective above just means that we don't have to import any module to use it – in the same way that java.lang classes don't need to be imported.]

The actual number 2^32 is, of course, too high to be represented by 32-bit integers. I'm a bit worried by various large numbers being mentioned (see also the 360 degrees, for angular velocities, in Question 40 (2007)). There is no need for large numbers in this exercise.

If we really need a power operator for integers, we can define our own:

    --* This computes a restricted integer power (not very efficiently).
    --  The power size must be positive.
    --  If the numbers are too large, there will be arithmetic overflow.
    -- @param x The number to be raised
    -- @param y The raising power (must be >= 0)
    -- @return [@ref x]^[@ref y]
      INT result:
          result := 1
	  SEQ i = 0 FOR y
            result := result*x
        RESULT result

To use this function, just use the specified symbol as an infix operator – for example:

    answer := n^i

This demonstrates two further mechanisms in occam-pi (that are not part of this course module): in-lining and user-defined operators.

The in-lining doesn't change any semantics – it just removes the function call overhead (inserting code for the body of the function wherever the call is made).

We can build new operators as single or double symbols, using any exisiting operator symbol (or ^, @, &, %, ...). As is normal, operator symbols can be overloaded – but each operator should be defined for a unique operand-type-result-type signature (otherwise, usual block-structure scope rules hide the previously defined operator for that signature). Operators are either infix binary or prefix unary (respectively two-parameter or one-parameter operator functions). If we put such things in some appropriate occam-pi module, the language acquires new operators. To this extent, occam-pi is user-extensible.

But this is an aside ... I still don't think you need a power operator. What you might need (and which the code already uses in compute.speed) is left-shift, <<, and right-shift, >>. So long as it doesn't overflow:

    n << i

shifts the bit pattern in n left by i bits. If n were positive, this multiplies it by 2^i (so long as there is no numeric overflow). Similarly:

    n >> i

shifts the bit pattern in n right by i bits. If n were positive, this divides it by 2^i (rounding towards zero). Maybe this is what you are after?

Keywords: cylons , operators , power

Referrers: Question 43 (2007)

Question 1 (2007):

Submission reference: IN1271

What is the bitwise-exclusive-or operator in occam?

Answer 1:

It's "><".

Keywords: operators


Question 102 (2004):

Is it possible to specify more than one condition in an "IF" process ? For example:

      x = 0 AND y = 0
        -- do something

If so which operators should be used ? When I compile something similar to the above I get an error saying:

    Expected new line, found AND

Answer 102:

This error occurs because you need explicit bracketing (occam has no operator precedence), even though the alternatives don't make much sense in this case. The correct way to write that would be:

      (x = 0) AND (y = 0)
        -- do something

Keywords: q7 , operators


Question 25 (2002):

What does each of this mean?

  /\, \/, ><, >> and <<

Answer 25:

These are described in slide 4-35 and section 1.2 of the Checklist paper. From there, you can infer that they are infix binary operators between INTs and that they return INTs. However, those pages does not say what those operations were! For that, you need to have attended the lecture when they were presented.

They are (mostly bitwise) logical operations:

  /\  - bitwise anding (between the two operands)
  \/  - bitwise oring (between the two operands)
  ><  - bitwise exclusive-oring (between the two operands)

  >>  - logical shift right (by right-operand number of bits)
  <<  - logical shift left (by right-operand number of bits)

The logical shifts are the same as in Java. They are not circular shifts - zeroes are pulled in to fill empty bits.

There is also the prefix unary operator:

  ~   - flip all the bits in the operand

These operators enable low-level (i.e. efficient) bit-twiddling to be done. This is needed to access specific bit fields common, for example, to memory mapped registers.

Note: these operators are overloaded so that they can be used on INT16s, INT32s, INT64s and BYTEs, as well as on INTs. The two operands must be exactly the same type - and the result of the operation is that same type. The bitwise operators are associative - for example, we may write:

  a /\ b /\ c

without any brackets. This contrasts with the + operation, which require brackets for a three-way add since, of course, with fixed precision numbers:

  a + (b + c)   is not equal to   (a + b) + c

and so we have to put in brackets to say what we want!

Keywords: operators

Valid CSS!

Valid XHTML 1.0!

This work is licensed under a Creative Commons Attribution-Share Alike 3.0 Unported License.
Last modified Mon May 20 13:50:28 2013
This document is maintained by Fred Barnes, to whom any comments and corrections should be addressed.