PDA

View Full Version : Expressing a number > a long

Jimmy W.
03-23-2009, 01:22 AM
I need to deal with some numbers that are larger than a long, to be specific a max value of 281_474_976_710_655 a WORD that would hold the carry bit and a LONG for main storage, does anyone have any good functions to move the carry bits over or to convert the resulting number to a string, and how would you do math operation on the number? I would need to multiply the number by .19 how would you accomplish this with the carry WORD? I just cant wrap my head around this for some reason, working with standard numbers is easy enough.

Jimmy

Post Edited (Jimmy W.) : 3/22/2009 7:22:45 PM GMT

StefanL38
03-23-2009, 05:00 AM
How about using the floating point math-objects ?

Mike Green
03-23-2009, 06:16 AM
Any kind of multiple precision arithmetic should work. For example to add two numbers B1,B0 and A1,A0 to get C1,C0:

C0 := (A0 + B0) // 1_000_000_000
C1 := A1 + B1 + (A0 + B0) / 1_000_000_000

Multiplication and division works just like the way you do it by hand with decimal digits except here the digits are 0 to 999_999_999.

To convert to a string, you just use division and its remainder to break apart a multiple precision number into decimal digits (dividing by 10).

To multiply by 0.19, multiply by 19, then divide by 100 all in multiple precision.

If you want to use "digits" that are powers of two like \$01000000, you could use shifts and masks to get the quotient and remainder.

If you need negative numbers, you might keep the sign in a separate variable. It makes the logic easier.

Post Edited (Mike Green) : 3/22/2009 11:23:31 PM GMT

MagIO2
03-23-2009, 06:37 AM
I suppose you don't get good answers, because your question is not so easy to understand. The max. number you have is \$FFFF FFFF FFFF, so it would fit in one word and one long. You mention a word and a long but you also mention that you want to have the carry bit in a word. That does not fit. Next you mention a fraction.

I did not have a look into the floating point object jet, but floating point is of course good for fractional numbers, but it is not necessarily good for storing numbers with 15 digits. I guess simple implementations of float would simply use longs to store a float. And you can't store that big number in it without loosing accuracy.

What could help here is to have fixed-point arithmetic. Use 2 longs to store a number. 6byte for the integer-part and 2byte for the fraction. Then you can store values up to your max and fractions in it. To find out how math works with this kind of numbers, you only have to know a little bit of the mathematical rules:
(A1+B1+C1)*(A2+B2+C2)=(A1+B1+C1)*A2 + (A1+B1+C1)*B2 + (A1+B1+C1)*C2 = A1*A2+B1*A2+C1*A2+A1*B2+B1*B2+C1*B2+A1*C2+B1*C2+C1 *C2

A => is the most significant long
B => is the most significant word of the 2nd long
C => is the least significant word of the 2nd long holding the fraction

Try to find out what each simple multiplication means and what to do with carrys. E.G. for A1*A2 a carry would mean that your result is too big.
For B1*B2 (which is a 16bit multiplication) you get a 32bit result. So the upper 16bit have to be added to Aresult. And so on.

Jimmy W.
03-23-2009, 09:09 AM
MagIO2 said...

(A1+B1+C1)*(A2+B2+C2)=(A1+B1+C1)*A2 + (A1+B1+C1)*B2 + (A1+B1+C1)*C2 = A1*A2+B1*A2+C1*A2+A1*B2+B1*B2+C1*B2+A1*C2+B1*C2+C1 *C2

A => is the most significant long
B => is the most significant word of the 2nd long
C => is the least significant word of the 2nd long holding the fraction

Try to find out what each simple multiplication means and what to do with carrys. E.G. for A1*A2 a carry would mean that your result is too big.
For B1*B2 (which is a 16bit multiplication) you get a 32bit result. So the upper 16bit have to be added to Aresult. And so on.

That was exactly what I was looking for, the original number would be a max value of \$FFFF_FFFF_FFFF no decimal places

Division would only happen once I process the number, and that itself would be stored elsewhere.

You are correct I was a bit confusing I meant that the first WORD would hold the overflow(carry) of the long thereby extending it to fit my max number, I did not think to do 16 bit math in a temp long, result that is perfect, I will just have to write routines to add or subtract manually.