Shop OBEX P1 Docs P2 Docs Learn Events
Expressing a number > a long — Parallax Forums

Expressing a number > a long

Jimmy W.Jimmy W. Posts: 112
edited 2009-03-23 02:09 in Propeller 1
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

Comments

  • StefanL38StefanL38 Posts: 2,292
    edited 2009-03-22 22:00
    How about using the floating point math-objects ?
  • Mike GreenMike Green Posts: 23,101
    edited 2009-03-22 23:16
    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
  • MagIO2MagIO2 Posts: 2,243
    edited 2009-03-22 23:37
    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.Jimmy W. Posts: 112
    edited 2009-03-23 02:09
    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.
Sign In or Register to comment.