Internet PLC Forum

General => Technical support => Topic started by: Lorne Van Dusen on June 22, 2018, 10:46:31 AM

Title: 16 or 32 bit DM confusion
Post by: Lorne Van Dusen on June 22, 2018, 10:46:31 AM
I had some spare time and decided to read the manual again and I found an issue that seems to be confusing.
The manual shows 2 examples Decimal IF DM[1] <> -1234 CALL 5 : ENDIF and in hex IF DM[1] <> &HFFFFFB2E CALL 5 : ENDIF
Now its my understanding that the value -1234 or FFFFFB2E are 32 bit values
So why does it allow you to use DM[1] which is 16 bit instead of using DM32[1] which is 32 bit?
Title: Re:16 or 32 bit DM confusion
Post by: support on June 22, 2018, 03:20:32 PM
In TBASIC all operators are operating on 32-bit  number.

Any integer numbers are always converted into 32-bit integer before applying the math or comparison operation.

So even if a number is contained in DM[n] the number is first converted ito a 32-bit number and thus any comparison has to be made against a 32-bit number. If DM[n] contains a negative number it will be sign-extended during conversion.
Title: Re:16 or 32 bit DM confusion
Post by: garysdickinson on June 22, 2018, 03:28:10 PM
Lorne,

I will try and explain how TBASIC works with data that is either stored in 8,16 or 32 bit variables or started out life as a 8,16 or 32 bit variable.

I will not discuss floating point stuff, but bear in mind that certain PLCs work with 32-bit floating point values.

Rule #1 TBASIC, internally, only deals with 32-bit signed integers.  

But, the PLC allows you to store and retrieve integers from 8,16 and 32 bit storage.  DM allows 16 and 32 bit access.  EEPROM can be accessed as 8,16 and 32 bit integers.  Some TBASIC functions return 8 or 16 bit values, and you may get surprised when your code does not function as you had hoped.

Signed Integer Rages for 8,16 and 32 bit variables:

Size in BitsMax DecimalMax HexMin DecimalMin Hex
81277F-12880
1632,7677FFF-32,7688000
322,147,483,6477FFFFFFF-2,147,483,64880000000

Rule #2 How are things stored in 8/16/32 bit variables.  If the variable is "too big" to fit in a given size variable, then only the least significant bits can be used.  As an example, if you try and store a value of 18,264 (&h4758) in an 8-bit variable only the least significant 8-bits will be used.  The 8-bit variable will now be 88 (&h58).  You may lose some precision.

Rule #2 is a bit like me with shoes.  I wear a size 14, to fit into a size 8 I will need to lop off my toes.

Back to Rule #1: TBASIC only actually works with 32-bit signed variables. If your TBASIC code uses 8 or 16 bit data sources, the 8 or 16 bit values will be "signed extended" to a 32-bit signed integer before it will be used.

Why is this important?  If you read an 8-bit value from a serial port using the INCOMM(n) command and the 8 bit value read from the communication port is &hA3 (-93 decimal)

    A = INCOMM(3)
[/font][/color]
The value assigned to the variable, A, will be &hFFFFFFA3 (-93 decimal).  This is an example of sign extension.

The following code will fail:

    A = INCOMM(3)
    If (A = &hA3)
        ' do something if the character was &hA3
        '
    endif
[/font][/color]
Why will it fail?  The variable A will hold &hFFFFFFA3 and it is being compared against &h000000A3.  The hexadecimal constant, &HA3, is treated by TBASIC as being a 32-bit value and TBASIC just compares one 32-bit thing against another.

Lorne.  This is just the way that TBASIC works.  It's not wrong, but it is not clearly documented by TRI.

If you can use DM32[] for storing integer data, then only use DM32[] method.  Now anything in A..Z and DM32[] will be 32-bit and TBASIC will not need to sign-extend or truncate data.  Same goes with integers stored in EEPROM, use the 32-bit access methods.

Oh, and your comment about "-1234 or FFFFFB2E are 32 bit values" is not exactly true.  -1234 can be accurately represented by both 16 and 32-bit signed variables.

Best regards,

Gary D*ckinson