Operand size promotion, signed or unsigned

Language reference ›› Statements ›› Assignments and expressions ››
Parent Previous Next

PMP uses the smallest possible size for evaluating each term in an expression and promotes its internal accumulator size as needed, so mixing types in expressions is not reversible.


Promotion rules:


Usually, all HLL promote expressions terms to their common integer size.

In Delphi64 it is 64-bit.

In Delphi32 it is 32-bit.

In TP integer size was 16-bit.

In PMP, to minimize math overhead and code size, even if PMP's integer size is 16-bit, the default size is 8-bit.


Some examples to understand what these rules imply:

So with PMP: <16-bit variable> := <8-bit expression> * <8-bit expression> overflows as the multiplication will be 8-bit.

In TP <16-bit variable> := <8-bit expression> * <8-bit expression> does not overflow as each term is promoted to 16-bit and the multiplication will be 16-bit.  

In TP <32-bit variable> := <16-bit expression> * <16-bit expression> overflows as the multiplication will be 16-bit.

In Delphi <32-bit variable> := <16-bit expression> * <16-bit expression> does not overflow as each term is promoted to 32-bit and the multiplication will be 32-bit.  


Possible overflows never produce any warning; for the multiply case you may use <16-bit variable> := MUL16(<8-bit expression>, <8-bit expression>).

A possible truncation will produce a warning message.


Mixed types:


A typical example is also to compare an INTEGER to a WORD. Since a WORD may be >32767, both are expanded to LONGINT before to compare, so the result is accurate.

Since PMP has no 128-bit integers (even internally), this cannot apply to BIGINT / BIGWORD compares, so such a mixed compare is made SIGNED.

An automatic term widening produces a warning. Widening may generate high costs in terms of code size and execution time.

For math operators, if one term is signed, the result is signed else it is unsigned.

When needed, PMP may expand to floating point if one term is a FP. Assignment of a FP to an integer variable (in $STRICT OFF mode) or an integer to a FP variable is allowed in PMP (with warning in the FP => integer way); the compiler generates automatically the appropriate conversions.

Please note that PMP internal FP routines use REAL format for precision; SINGLE expressions are always converted to REAL before computing. SINGLE is provided for 32-bit IEEE compatibility and variable storage reduction.


In the following code:


VAR B1, B2, B3, B4: BYTE; W1, W2: WORD;
// possible overflow on byte multiplication if (B1 * B2) > 255
...
B1 := B1 * B2 * W1 + B3 * W2;


The expression is evaluated as:


B1 := BYTE(WORD(B1 * B2) * W1 + WORD(B3) * W2);


This is not the same as:


VAR B1, B2, B3, B4: BYTE; W1, W2: WORD;
...
// No overflow on byte multiplication
B1 := B1 * W1 * B2 + B3 * W2;


Where the expression is evaluated as:


B1 := BYTE(WORD(B1) * W1 * WORD(B2) + WORD(B3) * W2);


Note: both cases will produce a warning message for byte truncation on B1 assignment.

Be careful to use the highest precision term at a leftmost possible position if intermediate results may overflow.