Go to the Next or Previous section, the Detailed Contents, or the Amiga E Encyclopedia.


A.8 Signed and Unsigned Values

This is a quite advanced topic, but might be the cause of some strange bugs in your programs. Basically, E does not have a way of differentiating signed and unsigned values from, say, the LONG type. That is, all values from the 32-bit, LONG type are considered to be signed values, so the range of values is from -2,147,483,648 to 2,147,483,647. If the values from this type were taken to be unsigned then no negative values would be allowed but more positive values would be possible (i.e., the range of values would be from zero to 4,294,967,295). This distinction would also affect the mathematical operators.

In practice, though, it is not the LONG type that can cause problems. Instead, it is the 16-bit, INT type, which again is considered to be signed. This means that the range of values is -32,768 to 32,767. However, the Amiga system objects contain a number of 16-bit, INT elements which are actually interpreted as unsigned, ranging from zero to 65,535. A prominent example is the proportional gadget which forms a part of a scroll-bar on a window (for example, a drawer window on Workbench). This works with unsigned 16-bit values, which is at odds with the INT type in E. These values are commonly used in calculations to determine the position of something displayed in a window, and if the INT type is used without taking into account this signed/unsigned problem the results can be quite wrong. Luckily it is very simple to convert the signed INT values into unsigned values if they are part of some expression, since the value of any expression is taken from the LONG type (and unsigned INT values fit well within the range of even signed LONG values).

PROC unsigned_int(x) IS x AND $FFFF

The function unsigned_int, above, is very specific to the way the Amiga handles values internally, so to understand how it works is beyond the scope of this Guide. It should be used wherever an unsigned 16-bit value is stored in an INT element of, say, an Amiga system object. For example, the position of the top of a (vertical) proportional gadget as a percentage (zero to one hundred) of its size can be calculated like this:

  /* propinfo is from the module 'intuition/intuition' */
  DEF gad:PTR TO propinfo, pct
  /* Set up gad... */
  /* Calculate percentage (MAXPOT is from 'intuition/intuition') */
  pct:=Div(Mul(100,unsigned_int(gad.vertpot)),MAXPOT)

Notice that the full 32-bit functions Div and Mul need to be used since the arithmetic may be well over the normal 16-bits used in the `/' and `*' operators.

The remaining type, CHAR, is not, in practice, a problem. It is the only unsigned type, with a range of values from zero to 255. There is a fairly simple way to convert these values to signed values (and again this is particular to the way the Amiga stores values internally). One good example of a signed CHAR value is the priority value associated with a node of an Amiga list (i.e., the pri element of an ln object from the module `exec/nodes').

PROC signed_char(x) IS IF x<128 THEN x ELSE x-256


Go to the Next or Previous section, the Detailed Contents, or the Amiga E Encyclopedia.