adccommunitymod (AutomationDirect) asked a question.

Ibox MATHBIN Problem

Created Date: August 29,2007

Created By: dramsier

**** This post has been imported from our legacy forum. Information in this post may be outdated and links contained in the post may no longer work.****

I'm using I-Boxes to do a fairly lengthy signed integer math calculation with intermediate results in V memory. Some of the values can be negative, unfortunately this includes the dividend in a divide operation. I 've discovered that the output of the MATHBIN Ibox is different if I create a negative dividend using constants versus having it stored in variable memory. For example, the equation (K1-K6)/K2 gives 0xFFFD, but if I store the dividend in Vmemory first and then reference it I get the following K1-K6 - > V430 (V430)/K2 gives 0x7FFD The former looks correct while the latter is clearly not what I intended. In either case, I would have expected them to be identical but they aren't. Is this an error in the Ibox implementation, or am I misunderstanding something about its use? Thanks, Dean


  • adccommunitymod (AutomationDirect)

    Created Date: August 29,2007

    Created by: dramsier

    I forgot to mention, DL06 using DS5.1

    Thanks,

    Dean

  • adccommunitymod (AutomationDirect)

    Created Date: August 29,2007

    Created by: franji1

    It's the implementation of the PLC architecture. It does not distinguish between signed and unsigned 16 bit values. It assumes 16 bit unsigned when it matters.

    You have to look at the actual instructions generated by the Math IBox.

    LD K1

    SUBB K6

    DIVB K2

    Let's just look at the K1-K6 portion:

    LD K1

    SUBB K6

    The accumulator is 32 bits, so when you did

    these first 2 instructions, the result is 0xFFFFFFFB in the 32 bit accumulator.

    When you do the DIVB K2, you get

    0x7FFFFFFD

    When you OUT to a WORD you get 0xFFFD in that Word (the lower 16 bits of the 32 bit accumulator)

    Now let's look at the 2nd example

    V430 / K2

    This generates

    LD V430

    DIVB K2

    I'm going to assume that it equals -5, but it is a 16 bit register, -5 is 0xFFFB, so when you do a LD V430 you end up with 0x0000FFFB in the accumulator.

    When you do the DIVB K2 on that 32 bit value you get 0x00007FFD, which is what you are seeing.

    There is no "signed math ", although it works when doing ADD and SUBTRACT due to the Modulo Math involved. However, when doing MULTIPLY or DIVIDE, there must be "sign extension " operations done on the MSBit. This would be bit 15 on a 16 bit binary number.

    There is no "Load 16 bit signed value " instruction that knows to extend the sign bit of V430 such that the accumulator ends up being 0xFFFFFFFB (extending bit 15 out all the way to bit 31).

    Other than doing it all by hand (i.e. doing the LD and checking the sign bit, then OR K FFFF0000 if it is set, etc.), your best bet is to conver everything to REAL, do all the math in MATHR, then convert back.

    Note that when converting BINARY 2 REAL (BTOR), it assumes UNSIGNED, so you would still have to look at the MSBit, save its status, do a 2's complement if it was negative, convert the absolute (positive) value to real, then set the MSBit of the real value to make the real value negative.

    Something like (this will put the "real " value of V430 into V2000/V2001 and handle conversion to negative numbers)

    STR B430.15

    OUT C0 // store whether V430 is negative or not

    LD V430

    INV

    ADDB K1

    BTOR

    ORD K80000000 // set the MSBit to make the IEEE Float be negative

    OUTD V2000

    STRN C0 // if it was NOT negative

    LD V430 // just convert V430 to REAL

    BTOR

    OUTD V2000

    Then in your MATHR IBox, do

    V2000 / R2

    This should give you -2.5

    Expand Post
  • adccommunitymod (AutomationDirect)

    Created Date: August 30,2007

    Created by: dramsier

    Thanks for the detailed explanation, I figured it would be something like this.

    This particular algorithm depends on integer math (dropping remainders etc) so I was unable to fix it with real numbers.

    However, I was able to get around it by modifying the algorithm slightly to guarantee that when the division occured it would always have positive numbers. I just wanted to understand the issue in case a future algorithm couldn't be fixed in the same way.

    In case anyone is curious, I was calculating the date of Easter (along with other holidays) for some building control work at our church. Algorithm is here http://aa.usno.navy.mil/faq/docs/easter.html

    Thanks!

    Dean

    Expand Post
  • adccommunitymod (AutomationDirect)

    Created Date: August 29,2007

    Created by: dramsier

    I'm using I-Boxes to do a fairly lengthy signed integer math calculation with intermediate results in V memory. Some of the values can be negative, unfortunately this includes the dividend in a divide operation.

    I 've discovered that the output of the MATHBIN Ibox is different if I create a negative dividend using constants versus having it stored in variable memory.

    For example, the equation

    (K1-K6)/K2 gives 0xFFFD,

    but if I store the dividend in Vmemory first and then reference it I get the following

    K1-K6 -> V430

    (V430)/K2 gives 0x7FFD

    The former looks correct while the latter is clearly not what I intended. In either case, I would have expected them to be identical but they aren't.

    Is this an error in the Ibox implementation, or am I misunderstanding something about its use?

    Thanks,

    Dean

    Expand Post