50 bit maths
g3cwi
Posts: 262
I need to do some maths (in Spin) that will need more than 32 bits. If I need say 50 bits, is the best way to break the calculation into 31 bits (to allow an overflow flag bit) and 19 bits?
Cheers
Richard
Cheers
Richard
Comments
Cheers
Richard
-Phil
Unsigned integer add and subtract are all that I need
Regards
Richard
You should be able to find some code that can be adapted. I doubt if you will find any 50-bit code.
Cheers
Richard
Regards
Richard
if the most significant bit of both least significant longs are zero, then there can be no carry. If both are one then there will always be a carry. If one is one and the other is zero, then if the most significant bit of the result of adding the least significant longs is zero then there was a carry, but if it is a one then there is no carry.
Subtraction is left as an exercise for the implementer.
Regards
Richard
There sure are a lot of ways to skin the ca., oh! sorry Browser.
My task for tonight is to try to figure out how these work. Operator precedence will clearly be rather important!
Thanks ericball.
Regards
Richard
Note: I've tweaked both equations to remove unnecessary terms.
C would not have been my starting point for precedence as I have no knowledge of C. However, I might well have assumed that SPIN follows the BODMAS order but I will check. Thanks for the heads-up that SPIN (and C) might diverge from BODMAS.
Cheers
Richard
I initially thought it was necessary to do an unsigned compare of zlsb with both xlsb and ylsb. But that appears not to be the case since, if a carry occurs, the sum will be less than each operand.
-Phil
Still no idea how it works though...
'tis powerful magic indeed.
Cheers
Richard
So how do the two form choices differ in size and speed ?
Some languages allow you to test the Carry Flag, or do in-line ASM of small code slices.
Cheers
Richard
You could try a good calculator ?
I've found this one great
http://www.zoesoft.com/console-calculator/ccalc-downloads/
So if we take Phil's example from above, in CCalc syntax it is
- but maybe my quick syntax morph lost something ?
CClac appears almost as a Text Editor, so you can copy/paste, and ; separates items on one line.
It allows named variables, and functions, and returns a Boolean 1/0 for <, >, =, tests
You can easily add checks, like the GotCy above.
and I think here I have correctly syntax--morphed
#12: [ zmsb = xmsb + ymsb + ((xlsb | ylsb) & !zlsb | xlsb & ylsb ) >> 31 ]
Cheers
Richard
I tend to work like Eric commented in #18, which is jump to a truth table, once you have it reduced to a small instance
Here we are looking for a carry, which has only 2 feed-bits, for 4 possible choices.
Then the important bit is confirming what you think is needed, actually works.
CCalc can display in Dec/Hex/Bin, so you can see how the underlying maths works.
What might confuse with these examples, is the trick of using zlsb to derive the carry, as it is not a pure input variable,
but it is the sum of the two variables. ( and must of course be computed first )
2. Spin uses only signed math, so the smallest number is $8000_0000 == -2_147_483_648, and the largest number is $7FFF_FFFF == 2_147_483_647.
3. To make an unsigned comparison using signed math, all you have to do is flip the sign bits of the operands, i.e. XOR with $8000_0000. This converts 0 to $8000_0000, the lowest signed number, and $FFFF_FFFF to $7FFF_FFFF, the highest signed number.
4. The comparison operators return -1 for true and 0 for false.
5. So if zlsb < xlsb (unsigned), there was a carry, and the expression returns -1; otherwise, 0.
6. Subtracting the result of the compare from the upper sum, therefore, is the same as adding 1 if there was a carry out of the lower sum; 0, otherwise.
-Phil
SpinLMM (you need bst), and the inline pasm by Beau (requires an extra cog).
Massimo