Rocket U2 | UniVerse & UniData

 View Only
  • 1.  UniVerse Numbers

    Posted 10 days ago

    All,

    We have a program that is doing a range of calculations that result in large integers. In some cases we are seeing overflow when negative numbers are being converted to their 2 complement e.g. when assigning it to a value in an array. 

    This is effectively what is happening (not the actual code and that's deep inside a complex routine).

    A = -1528596274

    B<C,D> += A

    B<C,D> shows as 2766371022

    If we take the assignment out of that program and put just the code into a standalone routine with the same numbers it works without modifying the number. Other calculations using that number also work.

    If we pass the value and array into a noddy three line subroutine to do the assignment, the value changes.

    Any attempt to manipulate the number e.g. ABS or even testing it (if A < 0) also coerces it to the 2s complement. 

    If we turn it into a string, the same.

    E = A : ''

    E is 2766...

    If we use string maths, the same.

    Other routines in the system are handling much larger numbers without a problem.

    Any ideas?



    ------------------------------
    Brian Leach
    Director
    Brian Leach Consulting
    Chipping Norton GB
    ------------------------------


  • 2.  RE: UniVerse Numbers

    PARTNER
    Posted 10 days ago

    Well that's curious.

    What version of UniVerse?

    How is A being assigned a value? 

    You may want to check A's descriptor type when it is first assigned using  DESCRINFO(1, A) and ensure it is an integer (1) or a float (2) and coerce it if not using INT(A) or A += 0.



    ------------------------------
    Henry Unger
    President
    Hitech Systems Inc
    Encino CA US
    ------------------------------



  • 3.  RE: UniVerse Numbers

    PARTNER
    Posted 10 days ago

    You may want to check to see what's in B<C,D> to ensure it's reasonable. You may even want to do:

    crt oconv(B<C,D>, 'MX0C')



    ------------------------------
    Henry Unger
    President
    Hitech Systems Inc
    Encino CA US
    ------------------------------



  • 4.  RE: UniVerse Numbers

    Posted 8 days ago

    Hi Henry

    Thanks for the response.

    At the point of checking the negative number (A = -1528596274)  it is definitely an integer according to RAID. It's assigned from various calculations - this is part of a large routine, lots of other subroutine calls, so what I've given is a very simple abstraction of what is happening. Even if we then add a line to the effect of G = 0; G += A, G is then set to the same (integer) 2766371022. If I try to coerce to string by concatenation, the same thing as a string. If we divide one of the constituents by 100 earlier on in the calculation so we end up with -15 million, it is all fine (though of course wrong). Tried using string maths in case that would help, but no.

    Again if we say IF A < 0 THEN .. or IF A[1,1] = '-' THEN ... it will jump that because it is treating it as the wrong number.

    So somewhere along the line it is getting coerced wrongly (presumably from an int to a uint)  but what is really confusing is if I take the logic out into another standalone routine just using the numbers above in the same account that wrong coercion does not happen. If I call that same routine passing in the variable, it does.

    This is on UV 11.3.5. I don't have enough of their environment and data to reproduce this on 11.4, 12 or 14.

    Does anyone from Rocket know of a case where this coercing can happen in one routine, but not others? Presumably something is being set in the run machine, but what...?

    Brian



    ------------------------------
    Brian Leach
    Director
    Brian Leach Consulting
    Chipping Norton GB
    ------------------------------



  • 5.  RE: UniVerse Numbers

    Posted 7 days ago

    an interesting problem.  I'm going to guess it will turn out to be more platform-dependent than UV-dependent.

    On uv11.4, WinSvr 2019 :

    CDS.BP BRIAN

         BRIAN
    0001 C = 3 ; D = 4
    0002 A = -1528596274
    0003 B = CONVERT( ';,', @AM:@VM, '1;2;31,31,33,-10000000000,34;5' )
    0004 CRT B
    0005 B<C,D>+= A
    0006 CRT B
    0007 *
    0008 B = CONVERT( ';,', @AM:@VM, '1;2;31,31,33,-10000000000,34;5' )
    0009 X = B<C,D>
    0010 X+= A
    0011 B<C,D> = X
    0012 CRT B
    >
    >RUN CDS.BP BRIAN
    1þ2þ31ý31ý33ý-10000000000ý34þ5
    1þ2þ31ý31ý33ý-11528596274ý34þ5
    1þ2þ31ý31ý33ý-11528596274ý34þ5
    >
    >VLIST CDS.BP BRIAN
    Main Program "SOURCE/CDS.BP.O/BRIAN"
    Compiler Version: 11.4.0.0
    Object Level    : 5
    Machine Type    : 11
    Local Variables : 5
    Subroutine args : 0
    Unnamed Common  : 0
    Named Common Seg: 0
    Object Size     : 126
    Source lines    : 12
    Object Date Time: 30 SEP 2024 08:37:17

    00001: C = 3 ; D = 4
    00001 00000 : 0F8 move           3  => C
    00001 00006 : 0F8 move           4  => D

    00002: A = -1528596274
    00002 0000C : 0F8 move           -1528596274  => A

    00003: B = CONVERT( ';,', @AM:@VM, '1;2;31,31,33,-10000000000,34;5' )
    00003 00012 : 03C convert        ";," "þý" "1;2;31,31,33,-10000000000,34;5"  => B

    00004: CRT B
    00004 0001C : 046 crtcrlf        B

    00005: B<C,D>+= A
    00005 00022 : 060 dyn_extract    B C D 0  => $R0
    00005 0002E : 004 add            $R0 A  => $R1
    00005 00036 : 064 dyn_replace    B C D 0 $R1  => B

    00006: CRT B
    00006 00044 : 046 crtcrlf        B

    00007: *

    00008: B = CONVERT( ';,', @AM:@VM, '1;2;31,31,33,-10000000000,34;5' )
    00008 0004A : 03C convert        ";," "þý" "1;2;31,31,33,-10000000000,34;5"  => B

    00009: X = B<C,D>
    00009 00054 : 060 dyn_extract    B C D 0  => X

    00010: X+= A
    00010 00060 : 004 add            X A  => X

    00011: B<C,D> = X
    00011 00068 : 064 dyn_replace    B C D 0 X  => B

    00012: CRT B
    00012 00076 : 046 crtcrlf        B
    00012 0007C : 190 stop
    >

    Warm regards,

    Chuck



    ------------------------------
    Chuck Stevenson
    DBA / SW Developer
    Pomeroy
    US
    ------------------------------



  • 6.  RE: UniVerse Numbers

    ROCKETEER
    Posted 7 days ago

    I am getting the same results as Chuck did, and was wondering what is the value prior to the operation?

    I expect you have checked, but If it is 4294967296 the the 2766371022 would be correct

    Also is the precision still set at the default, or did you change it?

    Lastly, What is the flavor of the account?

    Note sure what else to check at this point, but it does seem strange.

    Can you provide a small reproducible case, or is in dependent on the larger code set?



    ------------------------------
    Mike Rajkowski
    MultiValue Product Evangelist
    Rocket Internal - All Brands
    US
    ------------------------------



  • 7.  RE: UniVerse Numbers

    Posted 7 days ago

    Hi Mike/Chuck

    It is, as far as I can tell, only affecting this one routine (and they have thousands, it is a very mature application). They also typically deal with very large numbers. 

    As I stated, if I do a stand-alone routine to manipulate those numbers, not unlike the one Chuck has done, they all work correctly. So something must be getting set or happening inside the run machine to cause this particular routine, or routines called from this routine, to error in this bizarre way. It also means I can't create a simple reproducible case which is why I'm reaching out to see whether anyone else has suffered this. We're not hallucinating :)

    All the values are integral and precision is set to zero throughout this application.  INFORMATION flavor.

    Short of rewriting parts of the code in Python...



    ------------------------------
    Brian Leach
    Director
    Brian Leach Consulting
    Chipping Norton GB
    ------------------------------



  • 8.  RE: UniVerse Numbers

    Posted 7 days ago

    I'm grasping at straws here.  You  & Henry talked about A being an integer,   but along the same lines, what about $R0 & $R1  in the VLISTed code:

    00005: B<C,D>+= A
    00005 00022 : 060 dyn_extract    B C D 0  => $R0
    00005 0002E : 004 add            $R0 A  => $R1

    That's where the math happens.  (Maths to you Brits?  Or is this a single math?)

    I'm also curious about the value of B<C,D> before adding A.

    I'm trying to see the 2s Complement stuff but I can't make the numbers work. Ignoring sign, the numbers shown are 31- & 32-digit binary numbers.



    ------------------------------
    Chuck Stevenson
    DBA / SW Developer
    Pomeroy
    US
    ------------------------------