XML

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 cast

2012

Question 32 (2012):

Submission reference: IN2192

I'm quite far in Assessment 4 now   the only thing I need to get working is the animation!

I have a good idea for an animation and I can implement it correctly, but I come across a problem when using:

    PROC cursor.x.y (VAL BYTE x, y, CHAN BYTE out!)

My problem is that I need to use id (the reporting philosopher's id) in cursor.x.y so that I can line everything up correctly (in my code, the placement of Philosopher id and all of its reports is going to be relative to its actual id). However, when I try to do something like:

    cursor.x.y (1, id + 5, out)

this does not work, because cursor.x.y requires BYTEs for its first two arguments and my id (and, hence, id + 5) is an INT.

I think there's a really obvious step of conversion I'm missing here, but I just can't get my head round and find it. I need to convert my id INT into a BYTE. But how do I go about doing that?

Answer 32:

See Question 23 (2008), "Basics" slide 30, and casting.occ in your examples folder. This is also answered in Question 89 (2003), at some length in Question 73 (2000), in a way that may be useful for an animation is Question 66 (2000), and in Question 7 (2000).

For information on the subtleties of casting between number types (which may be useful for the next Assessment 5), see Question 111 (2003).

All the references above to previous items from these anon Q&As were found by following the "keyword index" link (at the top of each Q&A page) and the keyword "cast".

Keywords: q7 , cast


Question 18 (2012):

Submission reference: IN2170

I'm having a problem with my monitor method in Q4. If I write:

    BYTE k:
    keyboard ? k
      number ! k

obviously this won't work because of the change in data type. I've been stuck on this for the past few days, wondering if you could work out where I'm going wrong. I can't seem for the stream to continue – it just outputs nothing.

    PROC monitor (CHAN BYTE keyboard?, CHAN INT number!, integrate!)
      WHILE TRUE
        PRI ALT
          BYTE k:
          keyboard ? k
	    ...  (Ed: response hidden, but looks good)
          BYTE k:
          keyboard ? k
            SKIP          -- Ed: was this where you wanted: number ! k
    :

Answer 18:

First, the monitor needed for Q4 is a process and definitely not a method! ;)

But I don't know why you want to send down an INT-carrying channel a character received from a BYTE-carrying channel? If you really wanted to do that, you would have to cast the character into an INT:

    BYTE k:
    keyboard ? k
      number ! INT k        -- send ASCII code (as an integer)

See "Basics" slide 30, the program casting.occ in your examples folder and the Q&As linked from "cast" in the keyword-index of the anon Q&As ... for further information about type casting in occam-pi.

However, I'm sure you don't want to do this (and you certainly don't need to).

The code you posted (outlined in the question above) shows that you also have some misunderstanding about the ALT (or PRI ALT). You have two guards that are the same! This means: wait for the guard to become ready, when one becomes ready both become ready (because they are the same), the second guard will never be chosen (because it is listed after another guard that's ready in a PRI ALT), so execute the first guard and the process it is defending. Again, I'm sure that's not what you intended.

The monitor process does not need an ALT (or PRI ALT). All it has to do is wait for something to arrive on its keyboard? channel and respond (as you are doing in the response I hid in the code in your question).

Hope this helps.

Keywords: q4 , cast

2010

Question 54 (2010):

Submission reference: IN1950

I am searching a way to cast a REAL32 into an INT. On the Occamdoc, I find a way to convert a REAL32 into a string and then a string into an INT. Is there a way to do it more directly?

Answer 54:

Yes! You can directly cast a REAL32 to an INT – see Question 53 (2008) (which asks exactly the same question as you) and check under the keyword-index cast for other questions on casting. See also slide 30 of "basics" and the example program: examples\casting.occ.

Keywords: cast

2008

Question 53 (2008):

Submission reference: IN1719

On Task 3 for Life On Mars, I am trying to take a Real32 from the BLOB bearing field and add it to an INT.

This is to get its location from my starting point. However, I am unable to add it to an INT; and I am unable to cast it to an INT. I'm really stuck on this.

Answer 53:

Casting from REAL32 to INT requires you to specify what you want to do about the loss of precision in fractional numbers. See the last part of Question 111 (2003) for an explanation.

Other anonymous questions from the past dealing with casting are under the keyword cast if you need further help.

Keywords: mars , cast

Referrers: Question 54 (2010)


Question 23 (2008):

Submission reference: IN1609

How do I pass an integer to "cursor.x.y"? Whenever I try and do this, I get an error about incompatible types.

Answer 23:

The "cursor.x.y" procedure requires BYTE parameters. To pass an integer parameter, you must first cast it to a BYTE. Syntactically this is just "BYTE <expr>". For instance:

  cursor.x.y (4, BYTE (5 + x), screen!)

Where "x" is an integer variable. If the expression given is out of range for the target type (0-255 for BYTEs), a run-time error will be generated. See other questions relating to cast for more information.

Keywords: cast

Referrers: Question 32 (2012)

2007

Question 74 (2007):

Submission reference: IN1460

If we have:

  DATA TYPE FOO
    RECORD
      [20]INT data:
  :

  CHAN [20]INT c:

  [20]INT x:

Can we use casting, so that c transfers an element of type FOO? i.e is the code:

  c ? FOO x

correct?

Answer 74:

Your data type FOO is not cast compatible with [20]INT, so neither can be cast into the other. In occam-pi, casting is a special operator used (mostly) to change the representation of data values between types. For example, to change from REAL32 to an INT, we cast and the internal representation changes dramatically.

However, if we define a new type directly from an existing type:

  DATA TYPE BAR IS [20]INT:

then we can cast between BAR and [20]INT variables freely. In this case, no change in internal representation is needed.

The result of casting is a new piece of data. So your line:

  c ? FOO x

where x is an [20]INT and channel c carries [20]INT makes no sense. It works without the (illegal attempt to) cast with the FOO operator.

If you need to turn your x data from an [20]INT into a FOO, there is a way – but not by casting! If two types have respresentations of exactly the same size, they can be RETYPESd into each other. This is described in the occam-pi reference wiki, which is linked from the Co631 module web page. Take a look at Section 10.2 "Retyping". We did not cover this during the lectures, so it is not examinable. I'll probably include it in future years, just after abbreviations in the shared-etc sildes.

For information, since your FOO obviously has the same representation size as [20]INT, retyping is allowed between them. To retype your x, RETYPES it:

  FOO x RETYPES x:
  ...  for the duration of this block, x has the type FOO

Retyping is like abbreviating: all the rules about aliasing carry over, along with VAL retyping (like VAL abbreviations). So, if we only needed to use x as a FOO and not change it:

  VAL FOO x RETYPES x:
  ...  x has the type FOO here and it's a VAL

The retyping can go the other way. If f is a FOO variable, then:

  [20]INT f RETYPES f:
  ...  for the duration of this block, f has the type [20]INT

and:

  VAL [20]INT f RETYPES f:
  ...  f has the type [20]INT here and it's a VAL

Keywords: data-type , cast , retypes

2006

Question 59 (2006):

Submission reference: IN1038

I have the following report process, which is linked to the screen output channel. I want to be able to output the value of the INTs coming in on up and down, but I seem to have a casting issue.

    PROC report (CHAN INT up?, down?, CHAN BYTE output!)
      WHILE TRUE
        ALT
          INT a:
	  up ? a
	    output ! BYTE a
          INT b:
	  down ? b
	    output ! BYTE b
    :

As the screen output only accepts bytes, I have attempted to cast the integers. But when this process is run, the output is simply a bunch of smilies :-) ...

Is there is simple casting issue or do I have to attack this from a different angle?

Answer 59:

If the arriving INT were, say, 65 – then, casting it to a BYTE and outputting it to a channel connected to the main screen channel would print the symbol 'A'. Further, if the arriving INT were, say, 7 – then, casting it to a BYTE and outputting it to an channel connected to the main screen channel would cause the terminal to bleep (since 7 is ASCII code for BELL). Neither of these is probably what you wanted!

If the arriving INT were, say, 65 and you wanted to print the symbols "65" – then:

	    out.int (n, 0, out!)

would do the trick (assuming n is a variable holding the value 65 and out! is connected to the main screen channel).

But I don't recognise this report process in connection with the dining philosophers animation? What are you trying to do here??

Keywords: q7 , cast , out.int

2004

Question 101 (2004):

Do we need to use occam that is going to work on raptor or can we make use of the additions in the KRoC/Linux version. For example I'm considering using the STEP stride part for the replicator.

Next when using replicators, why can't I pass "i" into the "cursor.x.y()" PROC in this code ?

    PAR i = 8 FOR 5 STEP 2
      SEQ
        cursor.x.y (23, i, out)
        -- print stuff

Where "i" is the line number. The error is a type mismatch for parameter 2 in "cursor.x.y()". Surely "i" is an integer and should be accepted ?

Any help appreciated...

Answer 101:

For KRoC/Linux extensions (rather, occam-pi extensions), yes, using those is fine. We'll most likely be testing your code on such a machine.

The reason you can't pass "i" as a parameter is because "cursor.x.y" takes "VAL BYTE" parameters (not "VAL INT"). The solution for such things is to cast the parameter to the appropriate type:

    cursor.x.y (23, BYTE i, out)

Given the code you've got above, it should generate another error also (related to parallel usage), but that should be slightly more obvious.

Keywords: q7 , cast

2003

Question 111 (2003):

I found a problem doing a past exam question, while trying to cast an INT into a REAL32:

    INT sum:
    SEQ
      ...
      out ! values[index]; (REAL32 sum) / 10

but the compiler complains:

    "Type of operand invalid for exact type conversion REAL32"

Answer 111:

The designers of occam were very precise mathematicians, amongst other things. When you cast an INT into a REAL32, you don't expect precision problems - e.g. 42 should become 42.0 precisely (and it does).

However, large INTs do not convert exactly into REAL32s ... which only use (around) 24 bits to hold the mantissa (the actual number) and the rest to hold the exponent amd sign bits. But INTs use 31 bits to hold the actual number and 1 for the sign. Now, 31 into 24 don't go! So, only the first 24 bits go over when casting and the rest are implied zeroes (how many is defined by the exponent bits). The least precision bit of those 24 bits has to be decided. That decision requires you to specify whether that's to be done by rounding (to the nearest whole 24 bits value) or truncating towards zero. In occam, you must make that specification ... so your line should have been either:

    out ! values[index]; (REAL32 ROUND sum) / 10.0

or:

    out ! values[index]; (REAL32 TRUNC sum) / 10.0

depending on what you want. I don't know any other language (?) that is as fussy as this but the care is justified. Java/C will cast an int to a float without batting an eyelid ... does anyone know which way it decides that final bit when the number is too large ... I bet different C compilers will generate code that does different things ... may even be architecture dependent, so that the same compiler does different things on different architectures. May also be true for Java.

Of course, if your INT value is between ``-2**23'' and ``(2**23 - 1)'', then no decision about rounding-v-truncating is needed. But the occam cast is still `REAL32 ROUND' or `REAL32 TRUNC', which both give the same (and expected) result in these cases.

NB: the `10.0' divisor corrected above ... because occam only allows division of one type by the same type! And `10' is an INT and occam does also not allow automatic casting ... :-) ... you must say it to get it!!

PS: when casting the other way - from a REAL32 to an INT, we also need to specify what happens to the final bit. This is for a different reason though ... nothing to do with large numbers, but to do with fractional numbers. For example, should 42.7 become 42 or 43? Either may be what is required. What you get is what you say:

    INT i, j, k:
    REAL32 x:
    SEQ
      x := 42.7
      i := INT ROUND x         -- i gets 43
      j := INT TRUNC x         -- j gets 42
      k := INT x               -- will not compile!  (You must say!!)

See also the code on raptor in:

    /usr/local/courses/co516/examples/casting.occ

Keywords: cast

Referrers: Question 32 (2012) , Question 53 (2008)


Question 101 (2003):

I'm using cursor.x.y to make my interface but I've run into a problem. cursor.x.y takes two BYTEs and my program involves general formulas that take the fork/philosopher number and use it to calculate the co-ordianates of where the cursor needs to be. Is there any way of casting an INT straight into a BYTE of the same number? For instance, of the `x co-ord' needs to be ``(2 * philosopher number) + 2'', how can I get that from being an INT to being a BYTE I can use in `cursor.x.y' ?

Answer 101:

See Question 89 (2003).

Keywords: cast


Question 89 (2003):

Hi, I am having trouble with the `cursor.x.y' proc.

It will not accept the second parameter:

    INT id:
    ...
      [snip code]
      cursor.x.y (10, id, scr)

I thought an INT could be used as long as it isnt less than 0 or greater 255

Answer 89:

Such an INT can be used, but you need to cast it into a BYTE first. This can be done with: ``(BYTE id)''. If `id' is out of range for a BYTE, a run-time error occurs.

See also the answers to Question 74 (2000) and Question 73 (2000).

Keywords: cast

Referrers: Question 32 (2012) , Question 101 (2003)

2002

Question 10 (2002):

For q2, the keyboard channel takes a BYTE. How do I cast a BYTE to an INT?

Answer 10:

q2 does not require you to touch the keyboard channel - do you mean the screen one?

You can cast a BYTE to an INT ... but you don't want to do that for this question. You need to be able to output an (ASCII) character representation of an INT to the screen channel - but that's OK since that will be a sequence of BYTEs (which are the only things you can output to the screen). And that's done for you by the tabulate.int process, given to you in your q2.occ starter file.

If you really want to know about casting in occam, see Question 7 (2000).

Keywords: cast

2000

Question 74 (2000):

Is there anyway to cast INTs to BYTEs?

Answer 74:

Yes. See the answers to Question 7 (2000), Question 66 (2000) and Question 73 (2000) - for example.

Keywords: cast

Referrers: Question 89 (2003)


Question 73 (2000):

I have the following code:

    VAL INT i.mod.n IS i\n:
    in[i.mod.n] ? CASE
      thinking
        SEQ
          cursor.x.y (1, (i.mod.n * 4) + 5, screen)

which generates an error saying that the operator * has operand of different types. Is 4 not an INT as I assumed it would be? Or is it because i.mod.n is a VAL INT and 4 is a plain INT?

If it is the latter, surely not allowing a VAL INT to be muliplied together by an INT is being rather pedantic - seeing as they are obviously both INTs.

Anyway, as to a solution, is there any reason why i.mod.n is a VAL INT rather than just a plain INT which would allow me to mutiply with it without having to define all my other values as VAL INTs?

Answer 73:

The first two parameters for cursor.x.y are screen coordinates and they are of type BYTE - so BYTEs must be supplied.

The compiler looks for a BYTE as the first parameter and finds a 1 - that'll do! When it looks at the second argument, it finds an expression - an addition of two operands. The result has to be a BYTE which implies that both those operands must be BYTEs. The right operand is 5 - which is fine. The left operand is another expression - a multiplication of two operands. That result must be a BYTE and so, therefore, must be its two operands. Now, the right operand is 4 - which is fine. But the left operand is i.mod.n, which is an INT - not a BYTE. Error!

occam has a very simple rule about binary operators in expressions: both operands must have the same type and the same precision and the result has that same type and precision. There is no automatic casting between types - all casts, if needed, must be explicitly programmed. What-you-see-is-what-you-get.

Your other points about VAL are not relevant. VALs have no impact on types. A named VAL INT has INT type and may be freely added/multiplied/etc. with other INTs (whether VAL INTs or variable INTs). We want i.mod.n to ba a VAL because we don't ever need to change it - declaring it as a VAL will get the compiler to reject any code we might mistakenly write that tries to change its value.

To correct your code, you can't just declare i.mod.n to be a VAL BYTE. This is because it is used to index an array and array indices are always INTs. Instead, cast it at the point in your code where it needs to be a BYTE:

          cursor.x.y (1, ((BYTE i.mod.n) * 4) + 5, screen)

Of course, you have to be sure that evaluation of the above expression will always remain within the legal bounds of a BYTE (which are 0 through 255 inclusive). Hopefully, this will be the case.

Note: the above expression will cause the arithmetic to be performed using BYTE arithmetic. The following code causes INT arithmetic to be used (which on a SPARC or Pentium etc. will be more efficient - although that would not be not the case if we were compiling directly into silicon) and only casts the result into the needed BYTE:

          cursor.x.y (1, BYTE ((i.mod.n * 4) + 5), screen)

Keywords: type-mismatch , cast

Referrers: Question 32 (2012) , Question 89 (2003) , Question 74 (2000)


Question 66 (2000):

For question 7, I am trying to draw a boarder for the dining philosophers room. I can do it with lots of cursor.x.y and out.string procedures but this seems time consuming. I thought of doing it in a replicated PAR or replicated SEQ and I wrote this code:

  #INCLUDE "consts.inc"
  #USE "course.lib"

  PROC a (CHAN OF BYTE out)
    PAR i = 1 FOR 26
      SEQ
        cursor.x.y (4, i, out)
        out.string ("#", 0, out)
  :

  PROC test (CHAN OF BYTE keyboard, screen, error)
    PAR
      a (screen)
      ...  other things
  :

But when I compile it, it says there is a type mismatch in parameter 2 of cursor.x.y. This is the y coordinate that I am changing so that the character gets printed on the line below the first one to create a column like this:

      #
      #
      #
      #
      #
      #

Why does the compiler not like the second parameter of the cursor.x.y proceedure? Doesen't it just need to be a number?

Answer 66:

The second parameter of cursor.x.y needs to be a BYTE. Replicator control variables (e.g. your i) are INTs. You need to cast it into a BYTE:

        cursor.x.y (4, BYTE i, out)

See the answer to Question 7 (2000) for information on casting between occam types.

Your PAR replicator also won't work because it implies parallel outputs to the out channel - illegal! So it has to be a SEQ replicator. In any case, unless the occam kernel supports, and is running on a multiprocessor machine, the SEQ replicator for code like this will be faster than a PAR (which will have to startup and shutdown 25 software processes).

Your code would also be slightly snappier with:

  PROC a (CHAN OF BYTE out)
    SEQ
      cursor.x.y (4, 1, out)
      SEQ i = 1 FOR 26            -- the "2" could be anything though
        SEQ
          out ! '#'               -- don't need out.string for a single char
          cursor.down (1, out)
          cursor.left (1, out)
      out ! FLUSH

Keywords: q7 , type-mismatch , cast , cursor

Referrers: Question 32 (2012) , Question 21 (2001) , Question 74 (2000)


Question 7 (2000):

How can I cast an INT to a BYTE ?

Answer 7:

If x is an INT variable whose value is between 0 and 255 inclusive, then (BYTE x) is its BYTE equivalent. If x were outside the BYTE range, then (BYTE x) would give a run-time error.

In general, to cast from one primitive type to another, use the target type name as a prefix unary operator. For casting between certain types, rounding considerations become necessary (as the precision available in the target type is less than that of the source) and we have to state how the least significant bit is to be resolved (either by ROUNDing or TRUNCation). The details are low-level but, for some applications, crucial to get right. If you want to know more, look at the file:

  examples/casting.occ

which you should already have copied from the co516 course directory.

A key point to remember is that there is no automatic casting between data types in occam - what-you-see-is-what-you-get!

Keywords: cast

Referrers: Question 32 (2012) , Question 87 (2003) , Question 10 (2002) , Question 8 (2000) , Question 66 (2000) , Question 74 (2000)

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:26 2013
This document is maintained by Fred Barnes, to whom any comments and corrections should be addressed.