Shop OBEX P1 Docs P2 Docs Learn Events
Wrong value on 32 bits in Spin - Propeller — Parallax Forums

Wrong value on 32 bits in Spin - Propeller

EMHmark7EMHmark7 Posts: 93
edited 2014-04-23 10:18 in Propeller 1
Hi,

I assign a value DesiredPos:=ActualPos+24 (both DesiredPos and ActualPos are declared WORD)
Then I call a function without parameters
That called procedure uses the global var DesiredPos.

When I repeat several times the above mentioned, the DesiredPos goes above 128.
At that point, the called procedure using the global var value receives it with the 8 most significant bits all at 1,
So 144 gives 65424.

I already used ~~ and ~ for padding the sign for something else and it fixed the problem (not related to the actual problem), although I do not fully understand when to use it.

Here, I cannot use it on the 24 and I do not catch where I need to put it.
And the value did not kick the 16th bit sign of a word but just the 8th bit of a byte in a word value.
I suppose the black sheep is the 24.

As usual, your anyway always fast help appreciated.

Marc

Comments

  • EMHmark7EMHmark7 Posts: 93
    edited 2014-04-23 06:57
    I tried different things without success so far.

    I see that the value is already corrupted before the function call.
    So the problem seems to appear in the assignation statement.
  • JonnyMacJonnyMac Posts: 9,105
    edited 2014-04-23 07:01
    It would be easier to help by seeing your actual code. What are the legal range values for DesiredPos and ActualPos? It might be easier to use longs and then truncate them when a 16-bit value is required.
  • Mike GreenMike Green Posts: 23,101
    edited 2014-04-23 07:17
    You really need to post your entire program here (click on "Go Advanced" button for the Attachment Manager). ActualPos is treated as an unsigned 16-bit value, added to 24 using 32-bit arithmetic, then truncated to 16-bits and stored into DesiredPos. Perhaps something else is overstoring the most significant byte of one of these words. That's why we need to look at the rest of your program. ~~ and ~ are used when you want to store signed values in bytes (-128 to 127) or in words (-32768 to 32767) rather than unsigned bytes (0 to 255) or unsigned words (0 to 65535). They're used to sign extend the values in the 32-bit longs used internally for expressions to make them 32-bit signed long values.
  • EMHmark7EMHmark7 Posts: 93
    edited 2014-04-23 08:41
    Thanks for your reply. (I saw Mike's post after posting this one)

    The value limit is only limited by its type.

    At that point writing this post, I got ideas to experiment. (remains a practical question billow)
    I fixed it.

    The actual solution is (Not sure if it could be simpler):
    ___

    DesiredPos:=~~ActualPos-1000 'Desired position
    if ~~DesiredPos < ~~MinPos 'Reached minimum position
    DesiredPos:= ~~MinPos

    MoveToDo:=~~DesiredPos-~~ActualPos

    PC.nlTextDec(string("MinPos:") ,~~MinPos)
    'Debug monitoring. Even display should be sanitized otherwise misleading on actual value
    'Display is a good place to test for a right sanitization
    ___

    So I catched I need to sanitize these WORDS every time I read them in cases where they can get either negative values or values higher the +/1128.

    Even MinPos that was declared as BYTE for holding a small values such as 10,
    was changed to WORD, if it can help.
    But remains the point: Why do we need to sanitize with ~~ every move we do? What would be the right way to declare values so we do not need to load our listing with it? Delcare all Long values? (Or I miss a point).

    In my application, I could put a minimum limit to 0, for some stuff but still have to deal with values higher than 128 or 32768.
    But using the code in "what if" mode, shows the weaknesses of the algorithm. Always good to test with higher values so we know its limits.

    I wanted to point out my concerns (remaining questions) before I comment this:

    At that point writing this post, I got ideas to experiment. (so writing the first line of my post)
    In the Drupal community, they say, "There is a module for that!"
    Well, I could say in the Parallax world: "Write a post in their forum, either you get an answer in the following minutes, or you get the answer writing your post, Best support community I found" (Thanks mainly but not totally to the moderators, thanks to all members, it is the best feature of the Propeller.)

    So, ya, JohnnyMac, you help me find the answer, because I found it replying to your post.
    You made my day. Mike too, and not less.

    Marc
  • EMHmark7EMHmark7 Posts: 93
    edited 2014-04-23 09:13
    Mike Green wrote: »
    ~~ and ~ are used when you want to store signed values in bytes (-128 to 127) or in words (-32768 to 32767) (...) They're used to sign extend the values in the 32-bit longs used internally for expressions to make them 32-bit signed long values.

    All relevant (I think) that is in my program is:
    __

    DesiredPos:=~~ActualPos-1000 'Desired position
    if ~~DesiredPos < ~~MinPos 'Reached minimum position
    DesiredPos:= ~~MinPos

    MoveToDo:=~~DesiredPos-~~ActualPos
    __

    I am sanitizing the values when I read them, because I catched it was a kind of narrow misinterpretation from the compiler.
    Are you saying that we can sanitize them naturally when we write into them?
    Mike Green wrote: »
    ~~ and ~ are used when you want to store signed values

    How do we do it? Like this: ~~A:=B+C ? (I think I tried it and the compiler refuses it)
    and then, I wont need to use ~~ when reading them?

    In the case of DesiredPos:=~~ActualPos-1000
    ActualPos being a WORD,
    I suppose I need to sanitize that way, because ActualPos is not already a LONG, right?

    By the way, hope you saw my comment in post #5, I was thinking primarily about you. : )
  • JonnyMacJonnyMac Posts: 9,105
    edited 2014-04-23 09:29
    It seems like you're going through an aweful lot of [unnecessary] work. As Mike pointed out, the use of ~~ and ~ is to correct a long when the sign bit is in the wrong position. Using these operators on variables declared as words will not produce the results you're looking for. For example, if ActualPos is a word, then using ~~ only extends it to 16 bits, which would explain the odd value you indicated earlier.

    Use longs. If you need to transfer the lower 16-bits somewhere later, that's easily done with the .word[0] modifier.
    do_something(longValue.word[0])
    
  • EMHmark7EMHmark7 Posts: 93
    edited 2014-04-23 09:29
    For me, z:= ~~x, is a way to say a value x is signed, even if it would already be a LONG.

    Otherwise, how could we say in a formula that it is a signed value?

    I Hope you JonnyMac and Mike saw my non technical comment billow in post #5.

    Marc
  • Heater.Heater. Posts: 21,230
    edited 2014-04-23 09:33
    All LONG values in Spin are signed.
  • EMHmark7EMHmark7 Posts: 93
    edited 2014-04-23 09:37
    So, bottom of the line, if we process negative values or higher than 128 and 32768, we can remove all these ~~ and ~ if RAM/ROM space used by vars is not a concern by declaring them LONG. Tell me if I am wrong. I'll save you a post if I am right.

    Thanks,
    Marc
  • JonnyMacJonnyMac Posts: 9,105
    edited 2014-04-23 09:44
    One of the blockages to providing you a complete answer is understanding where your initial values are coming from. If you move a signed byte into a long and want to correct the sign (of the long), that's where ~ comes in. The same for ~~ after moving a signed word into a long.

    I write a LOT of Propeller code. I've never once been concerned about variable space. In actual fact, using bytes or words when longs are okay is actually more work for the compiler because the natural variable type of the Propeller is 32 bits. Of course, things like serial buffers will use arrays of bytes, but for simple variables, I always stick with longs. The few bytes lost to storage are made up for by [under-the-hood] code efficiency.
  • EMHmark7EMHmark7 Posts: 93
    edited 2014-04-23 10:18
    1) Beside global declare and init to a value in main, data comes from the stated line: DesiredPos:=ActualPos-1000

    2) I changed data type to LONG to these vars and removed all ~~ an ~. Everything works (so far) and it compiles with 2 LONG Less!

    Great!
    Thanks again.

    Marc
Sign In or Register to comment.