Shop OBEX P1 Docs P2 Docs Learn Events
Double Long Math? — Parallax Forums

Double Long Math?

JLT7JLT7 Posts: 19
edited 2011-12-22 14:22 in Propeller 1
Are there any objects available that do double long (64-bit) integer math? E.g. add/subtract two 64-bit values, divide a 64 bit value by a 32 bit divisor, multiply a 32 bit by a 32 bit value -> 64 bit result. Both signed and unsigned for all of these.

I looked in the object exchange and didn't see anything obvious.The only thing I found was an object called "Unsigned Integer Math Functions", which is just a small subset of the list above.

Comments

  • Mike GreenMike Green Posts: 23,101
    edited 2011-12-20 22:01
    The short answer is no. It's very easy to do multiple precision arithmetic in assembly since there are special instructions to make it easier. Multiplication and division are done in software and there also are instructions to make this easier. Attached is some documentation on this, but I've not seen standard objects that package this all up for easy use.
  • AleAle Posts: 2,363
    edited 2011-12-20 22:10
    ... see my sig :) of course it is a DIY :)
  • JLT7JLT7 Posts: 19
    edited 2011-12-20 22:36
    Mike Green wrote: »
    The short answer is no. It's very easy to do multiple precision arithmetic in assembly since there are special instructions to make it easier. Multiplication and division are done in software and there also are instructions to make this easier. Attached is some documentation on this, but I've not seen standard objects that package this all up for easy use.

    Yes, it's easy to do in assembly, but my main code is written in Spin and I don't want to waste a cog just to do math functions. Too bad it's not easily possible to mix Spin and in-line PASM on the same cog. :-(
  • cessnapilotcessnapilot Posts: 182
    edited 2011-12-20 22:48
    If your project requires 64-bit signed integer math, and you have to accomplish that task ASAP, then you can use the FPU64_ARITH object from OBEX. This object, however, needs the uM-FPU64 64-bit coprocessor (ca 30 $).

    Cheers,
    Istvan
  • AleAle Posts: 2,363
    edited 2011-12-21 02:02
    If he doesn't want to "waste" a cog, I don't think that a $30 solution is the way to go... but, maybe the other built-in functions are also needed....
  • Heater.Heater. Posts: 21,230
    edited 2011-12-21 02:10
    Write your code in C and use propgcc or Catalina.
  • AleAle Posts: 2,363
    edited 2011-12-21 02:49
    Heater... that is a very (very) good idea! So... does it support longlong ?
  • Heater.Heater. Posts: 21,230
    edited 2011-12-21 03:05
    Ale,
    does it [propgcc] support longlong ?

    Sure does. A long long addition compiles nicely to an add and addx when using size optimizations.

    Might be a good idea as long as:
    1) You know or would like to use C
    2) The resulting program fits in the Prop.
    3) You are willing to convert any Spin/PASM objects you are using from OBEX or wherever to C/PASM

    Size might be an issue as compiling to LMM code is a bit bigger than spin byte codes.
  • JLT7JLT7 Posts: 19
    edited 2011-12-21 10:37
    Heater. wrote: »
    Ale,

    Might be a good idea as long as:
    1) You know or would like to use C
    2) The resulting program fits in the Prop.
    3) You are willing to convert any Spin/PASM objects you are using from OBEX or wherever to C/PASM

    Size might be an issue as compiling to LMM code is a bit bigger than spin byte codes.

    Heater, a few questions for you:

    1) Is either Catalina or propgcc a turn-key install? I'm under a very tight time deadline (this project is an instrument that's going on a balloon launch, and the balloon is launching with or without my hardware). I probably have enough time to convert my code to C (which I know well), but not enough time to futz with getting a build environment working.

    2) Do these compilers support all of the functionality of Spin? Do they, for example, support bit ranges like this: outa[12..15] := %0110? I use this type of Spin shortcut heavily in my code and would have to convert everything to using | and & ~ in C, which will take time.

    3) How much larger will the C code typically be? With my existing spin code, I have around 2000 longs free.

    4) Does C use a cog for some purpose such as running a supervisor or interpreter? I'm using all 8 cogs in my current application and would need to do some serious restructuring if one or more cogs became unavailable.
  • ersmithersmith Posts: 6,099
    edited 2011-12-21 12:07
    JLT7 wrote: »
    1) Is either Catalina or propgcc a turn-key install? I'm under a very tight time deadline (this project is an instrument that's going on a balloon launch, and the balloon is launching with or without my hardware). I probably have enough time to convert my code to C (which I know well), but not enough time to futz with getting a build environment working.
    Catalina is an easy install, but it does not support 64 bit integers or doubles as far as I can see, so it probably won't be much help to you.

    propgcc is still alpha software, and is missing an IDE and debugger. If you're comfortable with command line tools and the "make" program it's a straightforward install.
    2) Do these compilers support all of the functionality of Spin? Do they, for example, support bit ranges like this: outa[12..15] := 10? I use this type of Spin shortcut heavily in my code and would have to convert everything to using | and & ~ in C, which will take time.
    They support the functionality of Spin, but not the syntax -- you have to use C syntax (so "outa[12..15] := %0100" would have to be recoded as something like "_OUTA = (_OUTA & 0xFFFF0FFF) | (0xb0010 << 12)").
    3) How much larger will the C code typically be? With my existing spin code, I have around 2000 longs free.
    It don't think we have a good feeling for this -- it depends on the application. The C code is compiled to LMM code, which can be twice as big as spin bytecodes, but the C compilers are usually better at doing things like common subexpression elimination to reduce code size. Both Catalina and GCC support putting code in external memory if you need more than 32K.
    4) Does C use a cog for some purpose such as running a supervisor or interpreter? I'm using all 8 cogs in my current application and would need to do some serious restructuring if one or more cogs became unavailable.

    GCC doesn't need any cogs beyond the one its running on. I think Catalina can be configured that way too.

    Eric
  • localrogerlocalroger Posts: 3,452
    edited 2011-12-22 12:42
    You can do 64 bit multiplication in Spin by doing the operation twice, the second time with the ** operator which returns the high long of the result. The ** operator is often used as an all-integer way to effectively multiply values by fractions less than 1 with very high precision.

    The problem with doing other wide arithmetic in Spin is that Spin doesn't make the carry and zero bits available after performing instructions like ADD and SUB. If you don't need all 64 bits and performance isn't an issue you can cheat by treating the high bit of the result as carry, masking it off, conditionally adding 1 to the high word, then clear the high bit, do the high long addition, test bit 0 of the high result to set bit 31 of the low long, then shift the high result right 1 and sign-extend it to set the sign bit. That should give you a properly signed 63 bit range.

    It should be possible to implement 64 over 32 bit division similarly, but you will have to test and conditionally set bits that would normally get carried over in the shift operations. Considering your cog situation and that you have plenty of code space left, I'd attempt something like this before getting more complicated.
  • JLT7JLT7 Posts: 19
    edited 2011-12-22 13:38
    localroger wrote: »
    You can do 64 bit multiplication in Spin by doing the operation twice, the second time with the ** operator which returns the high long of the result. The ** operator is often used as an all-integer way to effectively multiply values by fractions less than 1 with very high precision.

    The problem with doing other wide arithmetic in Spin is that Spin doesn't make the carry and zero bits available after performing instructions like ADD and SUB. If you don't need all 64 bits and performance isn't an issue you can cheat by treating the high bit of the result as carry, masking it off, conditionally adding 1 to the high word, then clear the high bit, do the high long addition, test bit 0 of the high result to set bit 31 of the low long, then shift the high result right 1 and sign-extend it to set the sign bit. That should give you a properly signed 63 bit range.

    It should be possible to implement 64 over 32 bit division similarly, but you will have to test and conditionally set bits that would normally get carried over in the shift operations. Considering your cog situation and that you have plenty of code space left, I'd attempt something like this before getting more complicated.

    That's what I'm doing now. As I said above, this would be easy if I could mix PASM code with Spin, but, alas, that's a can of worms.

    I'm surprised Parallax hasn't implemented this functionality as one of their "golden reference" objects as it's needed reasonably often when dealing with scaled fixed-point math that won't quite fit in 32 bit variables or where intermediate results are too large.

    I tried the propgcc compiler mentioned above, and it handles long long ints wonderfully, but I concluded I just don't have time to convert everything to C in the short time I have left for this project.
  • max72max72 Posts: 1,155
    edited 2011-12-22 14:22
    check the forum or the obex.. there is an inline PASM object.
    The other solution is spin LMM, available in the obex
    Massimo
Sign In or Register to comment.