Incorrect Result Using Add Function Block

Hello,

Recently I have been experimenting with the TIME,  TIME_TO_STR, and STR_TO_TIME functions.  As you know the STR_TO_TIME functions convert a time (string) to an integer which represents seconds.  My goal has been to convert a time to an integer, add a value to it, and then convert it back to a time (string).

Curiously, I am having issues doing the addition.  As an example:  I convert the time "2016-01-10T14:05:00" using STR_TO_TIME and the result is 1389362700 (one billion). So far, so good.   Next, I add 14400 to it and receive 1389377024.  Unfortunately Excel tells me that I should be getting 1389377100, which is a difference of 76.  

DeltaV
1389362700  + 14400 = 1389377024

Excel
1389362700  + 14400 = 1389377100

Various values give me various differences in answers. It seems as though the issue is related to a number in the billions - either an operand or the result.

I started out using 32-bit Signed Integers (range of +/- 2 billion) as my data type.  I have also tried using 32-bit Unsigned Integers (range of +4 billion).  I have performed this calculation using an ADD function block as well as structured text in a CALC block, both give me the same result.  I am using DeltaV v 13.3 with an SX controller.

Is DeltaV not capable of calculating numbers with accuracy at that size of value?  Is there another way I should have approached this?

Thank you,

Dave

  • My recommendation: always use 32-bit unsigned integer to store time. Also, be careful with function blocks. ADD works with floating point. This might be why you are losing precision.
    When I work with TIME, I always use CALC/ACT and work with parameters outside the block (inputs/outputs of a CALC block are again floating point, so you might lose precision again).
    So: use a CALC block, and instead of using OUT1:=IN1+14400, use ^/RESULT:=^/INPUT+14400.
  • In reply to István Orbán:

    Hi Istvan,

    I actually started out using the method you mention inside a series of ACT blocks.  I have a few parameters:

    - '^/PERIOD_TIME_I.CV', a UINT 32 that receives the time value from a TIME function
    - '^/PERIOD_ADD.CV', a UINT 32 that contains the seconds to add
    - '^/PERIOD_TIME_I2.CV',  a UINT 32 that contains the result.

    PERIOD_ADD is calculated based on some criteria earlier in the ACT block, but all three are related as follows:

    '^/PERIOD_TIME_I2.CV' := '^/PERIOD_TIME_I.CV' + '^/PERIOD_ADD.CV';

    I switched to trying with the ADD block because I was not getting the answer I expected.  In the image below, PERIOD_TIME_I2 is the result of the calculation expression above.  Unfortunately, it returns to me the exact same result.

    Thanks,

    Dave

  • In reply to dave_marshall:

    Dave,

    I just tried on v13 but using a virtual SX controller and my logic comes up with the correct calculation (make sure you have flashed the controller to v13.3).

    I have CURRENT_TIME_1, TIME_ADD, PARAM1 and PARAM2 all as 32bit Unsigned Integers and like István indicated, the ADD block is using floats which is causing your error. Check that you have all the parameters as 32bit unsigned integers and you are doing the math using the parameters as it should work.

    Here is my config and you can see the results:

    Regards,

    Matt

  • In reply to Matt Stoner:

    Hi Istvan and Matt,

    I found the issue.  I was performing a calculation to determine the value of Period Add above.  The calculation involved division and a TRUNC() command.  I finally realized that DeltaV was having to do a conversion from the result of the division to the UINT32 that occurs after the ACT block executes (http://www.emersonexchange365.com/operateandmanage/deltav/f/50/t/3158).  

    Once I moved the addition into an ACT block that executed after the ACT block with the TRUNC(), I got the correct result.

    Thank you for the help!