64 bit math
average joe
Posts: 795
After some work I'm ready to release the first version of my 64 bit (unsigned) math object. It allows adding or subtracting 64 bit numbers, as well as multiplying or dividing a 64 bit number by a 32 bit number. It's far from perfect. There's no checking for overflows or any other safeguards. This first version starts a cog, does the math, then stops the cog. I will be creating a second version that keeps the cog running as time permits.
Comments
I think step one should be to use 64 bit signed numbers (63 bit + sign) for everything. Here's a for instance on why.
a - b = c
c + d = f
if: b > a then c < 0
if d < c*-1 then e < 0
for example.
a = 0 , b = 10 , d = 0
a - b = 0 - 10 = c = -10
c + d = -10 + 0 = e = -10
in summary: a = 0, b = 10 , c = -10 , d = 0 , e = -10
a, b, and d are fine as unsigned numbers, but c and e would need to be signed numbers.
....
In turn, your life is easier if you you use signed math for everything. Otherwise you need to spend more time being careful that numbers never leave the positive number interval.
Any thoughts would be helpful!
*edit*
Just updated code with fully commented version. Still looking for any advice!
Also, fixed the address / data swap. Thanks for pointing that out!
*edit*
Code with suggested improvements :
Anyway, if that's your style, stick with it.
Just noticed, function parameters are still longs, so even if you only read words you'll have to advance by 4 (not 2, @nPtr == @hPtr + 4).
Re: long address. That's a great point! When I started writing, I had word variables to store the pointers in. But I decided that passing the DoMath variables to be better. And then never went back and changed the advance.
The lower 32 bits should be manipulated with add/sub instead of adds/subs.
*edit*
Found a couple errors already
The 64bit value is emitted to the serial console after each key press.
This logger uses 64 bit math.
http://code.google.com/p/propforth/wiki/Logger1Simple
The source code is included in the comments. The stuff that gets loaded is the same, but in base 64 encoding to load faster. Skip past that and the forth source to the assembler code.
Not sure if anyone else will find this helpful but once it's done I will be releasing under MIT license.
This is very interesting to me. I wonder why you have it launch the cog with each call instead of having a normal "Start" method to launch the cog? I don't remember the exact time, but launching a cog takes a bit of time and if one had a lot of math to perform, the current arrangement sure seems like it would slow the process down significantly.
I was envisioning something like F32 that launched a cog and waited for a command.
Did you not what to tie the cog up permanently?
Still doing some sanity checks and it seems to work okay. I do need to put in the comments that mul-div only use 32 bit multiplier / divisor...
Sounds good.
I haven't run into the need for 64-bit math myself but I'm pretty sure it's just a matter of time until I'll need/want it.
Thanks for posting your code.
Lawson
Honestly, no I don't want to keep it that way. Sadly I don't have much time to continue working on this. I have a TON of code to write and my deadline is quickly approaching. It will work for now since 99 iterations won't take that long and it's not called very often. I admit this object still could use quite a bit of work but it will have to wait.
http://academic.evergreen.edu/projects/biophysics/technotes/misc/bin_math.htm
for multiplying two 64 bit numbers that would be 64 iterations of 64 comparisons, then 64 numbers to add together. This would leave you with a 128 bit result. This would be pretty straight forward to program and would be a bit costly to run (~4100 simple math operations plus the add)...but not nearly as costly as adding the multiplicand the multiplier number of times (~2^64 add operations)
Nice job Joe on tackling this problem. Maybe this can be revisited in the future to expand and optimize a 64 bit math library.