Convert a 'signed' Word to a Long with minimum manipulation ?


Closed Thread
Results 1 to 8 of 8

Hybrid View

  1. #1
    Join Date
    May 2004
    Location
    NW France
    Posts
    3,653


    Did you find this post helpful? Yes | No

    Default

    Hi,

    I' d try a first thing ...

    Code:
     
    if Myword.15 then
     
    MyWord = Myword * -1 ' absolute value
    MyLong = MyWord * -1 ' the negative number
     
    Else
     
    MyLong = MyWord
     
    Endif
    certainly not the smartest ... but simple.

    *** IDEA : TO BE CONFIRMED ***
    Alain
    ************************************************** ***********************
    Why insist on using 32 Bits when you're not even able to deal with the first 8 ones ??? ehhhhhh ...
    ************************************************** ***********************
    IF there is the word "Problem" in your question ...
    certainly the answer is " RTFM " or " RTFDataSheet " !!!
    *****************************************

  2. #2
    Join Date
    Nov 2008
    Posts
    96


    Did you find this post helpful? Yes | No

    Default

    I guess I should see which way uses least code space too, but I just tryed to complile the first suggestion and it did that OK. I'll only know if the code runs as expected later today, when I burn a PIC and try it.
    I added this to my code.
    Code:
        lAC2        var Long            'Long variables for calibration values actually negative in my sensor
        lAC3        var Long 
        lMB         var Long
        lMC         var Long
    
    'Convert unsigned PBP Word var to signed PBP Long var.
    
            lAC2 = AC2                           'copy word to long   
            if AC2.15 then lAC2.HIGHWORD = $FFFF 'Check for negative, set top 16bits to all 1's if true 
            lAC3 = AC3                           'copy word to long
            if AC3.15 then lAC3.HIGHWORD = $FFFF 'Check for negative, set top 16bits to all 1's if true
            lMB = MB                           'copy word to long
            if MB.15 then lMB.HIGHWORD = $FFFF 'Check for negative, set top 16bits to all 1's if true
            lMC = MC                           'copy word to long
            if MC.15 then lMC.HIGHWORD = $FFFF 'Check for negative, set top 16bits to all 1's if true

  3. #3
    Join Date
    Nov 2008
    Posts
    96


    Did you find this post helpful? Yes | No

    Default

    Yes. The method above works well. I did not try the other way to see if it's tighter code though, I was happy to just push onwards.

    I discovered a issues with the rest of my calculations though, and I'd appreciate a comment from the 'Long literates' among us.

    I'll try to explain without a huge dialogue, if it's too vague let me know. Here goes...

    OK, this code, all the variables are Longs, except AC5, AC6 and MD which are Words.

    Code:
    X1 = ((lUtemp - AC6) * AC5) >>15  'find X1 - Note I needed the extra () around AC5 to get it to work
             X2 = (lMC << 11) / (X1 + MD)      'Find X2
            B5 =  X1 + X2                               'Find B5 from X1 and X2
            lCTemp = (B5 + 8) / 16    '>> 4      'Hey presto, lCTemp appears...
    Firstly I needed two sets of parenthesis around the X1 calculation, or it gave a bad result with only one around the 'lUTemp -AC6'.
    The original C code was like this though ( I changed the 2^15 to the shift right by 15).
    X1 = (UT - AC6) * AC5 / 2^15

    Second, in the last calculation, I got a bad result whenever the value B5 became negative, until I got rid of the >> 4 and made that a '/ 16'. Then the value of lCTemp worked OK below 0 degC (I used freezer spray). I thought a >> 4 shift was equivalent to a / 16, but here in this syntax it seems not.

    Can someone fill me in on why the shifts didn't quite work like a numeric divide here ?
    Perhaps something to do with signed math again ?

    In the end with the second brackets and a numeric divide the results were good, I'd just like to know why my 'fixes' worked so I don't bugger up the next stage...

    Thanks,
    Martin
    Last edited by mr.sneezy; - 27th May 2010 at 12:35.

  4. #4
    Join Date
    Nov 2005
    Location
    Perth, Australia
    Posts
    429


    Did you find this post helpful? Yes | No

    Default

    PBP's shift algorithms dont work on negative numbers. You either have to divide instead, or do something like this:

    lCTemp=(B5+8)>>4
    IF lCTemp.27 THEN lCTemp=lCTemp&$F0000000

    (Untested)

    *edit* note that the division will always round down (towards negative infinity) when shifting no matter if the number if positive or negative. e.g. 5/2 = 2, but -5/2 = -3 (only for shifting - not division)
    Last edited by Kamikaze47; - 27th May 2010 at 14:27.
    "I think fish is nice, but then I think that rain is wet, so who am I to judge?" - Douglas Adams

  5. #5
    Join Date
    Nov 2008
    Posts
    96


    Did you find this post helpful? Yes | No

    Default

    Thanks.
    It sounds like I should just avoid using the Shift type divides then with Longs...
    Martin

  6. #6
    Join Date
    Nov 2005
    Location
    Perth, Australia
    Posts
    429


    Did you find this post helpful? Yes | No

    Default

    Just to correct myself, the code in my last post should have been:

    lCTemp=(B5+8)>>4
    IF lCTemp.27 THEN lCTemp=lCTemp|$F0000000

    I accidentally used an AND instead of an OR
    "I think fish is nice, but then I think that rain is wet, so who am I to judge?" - Douglas Adams

Members who have read this thread : 0

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts