Announcement

Collapse
No announcement yet.

Convert VM_OVERFLOW part of Multiply result to unsigned?

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Convert VM_OVERFLOW part of Multiply result to unsigned?

    Hi,

    I am trying to play long videos on a uOLED-128-G2. I have encoded frames as images aligned with SD card sectors.

    I have 2 variables that I now want to use to perform a 32 bit multiplication, but can't fathom the behaviour of VM_OVERFLOW.

    I have figured out with print statements, that the sign of the operands will determine whether or not the resulting number in VM_OVERFLOW is 2's complement, but not how.

    What is the behaviour of VM_OVERFLOW when holding the result of a multiplication, and what is the correct way to convert this into unsigned representation?

    Sj

  • #2
    You mean a video with more than 65k frames?

    Why not just split it into two videos then? (and let the PmmC do the calcs)

    The overflow is just that, the overflow 'word'

    So 1234*5678 = 7006652 = 0x6ae9bc, so OVF() ( or the equivalent peekW(VM_OVERFLOW) ) would contain 0x6A and the result would contain 0xe9bc

    Mark

    Comment


    • #3
      Hi Mark,

      That's right. I have already encoded the video and have it playing, it's just the media offset calculations that are the problem.



      I see 1234 * 5678 works as expected: 0000 0000 0110 1010 1110 1001 1011 1100, or, 0x06A 0xE9BC, or, 106 -5700

      Lets say however I did: 1234*-5678 (i.e. 0x04D2 * 0xE9D2 == 0x04671644)...

      If that operation simply held the overflow, we'd expect the bit pattern to be:

      0000 0100 0110 0111 0001 0110 0100 0100

      But it isn't. When I display OVF() I get -107:

      0xFF95 : 1111 1111 1001 0101

      (the variable is as expected: 0001 0110 0100 0100, or, 0x1644, or 5700)

      The code I'm using is:

      var r,c;
      pokeW(VM_OVERFLOW,0);
      r := 1234 * -5678;
      c := OVF();
      print(c, " ", r);


      Again, if I do 0x8000 * 0x8000 I get 16384 0, exactly as you say, but when I do 0x04D2 * 0x8000 I get -617 0 (should be 0x2690000)


      So it seems that VM_OVERFLOW is storing overflows in 2's complement, when an operand is negative. That makes sense.



      However, then I come to calculations (actual example where my program fails) like this:

      Working:
      0x8590 * 0x2E ((-31344) * (46)) == 17FFE0
      VM_OVERFLOW: 23 (0x17) (or, -23 before converting to +ve)
      variable: -32 (0xFFE0)

      Fails:
      0x8591 * 2E ((-31343) * (46)) == 18000E
      VM_OVERFLOW: 22 (0x16) (or, -22 before converting to +ve)
      variable: 14 (0xE)


      How has the GOLDELOX computed the overflow of the second operation as 22 when it should be 24?
      Last edited by sebjf; 7th August 2017, 05:26 AM.

      Comment


      • #4
        (Have a look at the image below, produced by a set of calls like this:

        a := 0x3590;
        r := a * b;
        c := OVF();
        print(a,"*",b,"=",c, " ", r, "\n");

        It seems I can keep multiplying assuming the above, until about 0x8590 at which point the overflow starts decreasing...)
        Attached Files

        Comment


        • #5
          Just consider the result two halves of a 32 bit signed integer and it should all make sense.

          Maybe also do it in excel, you will see the same answers.

          Mark

          Comment


          • #6
            Got it, (seems obvious now...) I modified my code to subtract the equivalent unsigned offset due to the expansion bits and its working now.

            Thank you Mark.

            Comment

            Working...
            X