DIV32 instead of floating point routines?


Closed Thread
Results 1 to 7 of 7
  1. #1
    Tomasm's Avatar
    Tomasm Guest

    Question DIV32 instead of floating point routines?

    Hi everyone,

    I have to calculate with 16bit numbers, but the result has to be 24 or 32 bit:

    result = a * 5 / 3 ' 0 < a < 60000

    The result sometimes doesnt fit in a word variable. Therefore I used the floating point routines, but that needs to much flash. Is there a way to do this calculation with div32?

    Thanks in advance,

    Best Regards,

    Tomas

  2. #2
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default

    I suppose it depends on the accuracy you need. But if you only want the integer of the result, here's one way to do it.

    Code:
    a          var  word      ' 0-60000
    result     var  word[2]   ' 32-bit result, although largest is 17-bit with input of 0-60,000
     ResHigh   var  result[1]
     ResLow    var  result[0]
    remainder  var  word
    temp       var  word
    
    a = 60000    ' a test number
    
    ResLow = a / 3
    remainder = a // 3 * 15 / 10
    temp = ResLow - 13107
    ResHigh = temp.15 ^ 1
    ResLow = ResLow * 5
    Reslow = Reslow + Remainder
    
    LCDout $FE,1,Hex4 ResHigh,":",hex4 ResLow
    I know it looks strange, but try it. It works.

    Best regards,
    &nbsp;&nbsp;&nbsp;Darrel

  3. #3
    Tomasm's Avatar
    Tomasm Guest


    Did you find this post helpful? Yes | No

    Thumbs up

    Hi Darrel,

    yes, a integer result is sufficent for me.

    I coded a solution with Div32 but your solution is much shorter.

    Thank you very much, Darrel.

    Best regards,

    Tomas

  4. #4
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default

    Hi again Tomas,

    I wrote that example rather quick, just trying to beat Melanie to the punch.&nbsp; After looking at it again, I saw that it could be reduced even further. This way uses fewer variables, and is a bit shorter too.
    Code:
    a          var  word      ' 0-60000
    result     var  word[2]   ' 32-bit result, although largest is 17-bit
     ResHigh   var  result[1]
     ResLow    var  result[0]
    
    a = 60000    ' a test number
    
    ResLow = a / 3
    ResHigh = ((ResLow - 13107) >> 15) ^ 1
    ResLow = ResLow * 5 + (a // 3 * 15 / 10)
    Best regards,
    &nbsp;&nbsp;&nbsp;Darrel

  5. #5
    misk's Avatar
    misk Guest


    Did you find this post helpful? Yes | No

    Default

    Hi Darrel,
    can You explain how to reach that result?
    Thank You.
    Misk

  6. #6
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default

    Oh geez, sorry misk, I missed this question.

    Basically, it just uses the divide first to reduce the size of the numbers, then does the multiply. This helps keep it within the 65535 limit. (a / 3 * 5) is the same as (a * 5 / 3)

    Since the largest result of (60,000 * 5 / 3) = 100,000 which is 0001:86A0, you really only have to worry about 1 bit above the 65535 limit. In this case it worked out nicely that the largest number you can multiply by 5 and still be within 65535 is 13107. Anything larger, and you just add an extra bit, then do the multiply like normal.

    After dividing the original number:
    ResLow = a / 3

    If you subtract 13107 from it, and it becomes negative, then the twos compliment value of the negative number will have bit 15 as a 1. This means that the number is not large enough to cause an overflow. So, the next statement just isolates that bit15 and inverts it with an xor operator (^ 1). This now becomes the low bit of the high word.

    ResHigh = ((ResLow - 13107) >> 15) ^ 1

    It kind of like saying.. If (a / 3 * 5) > 65535 then ResHigh = 1.
    If you could actually do that in PBP, it would be much easier.

    Now that the High word is complete, you can just do the multiply times 5 and just let it overflow (if it does).

    Finally, in the first divide by 3, there is usually something left over. It's always either a 0, 1, or 2 (a // 3) the modulas of 3.

    To get the decimal of that modulas, you would normally divide that number by the original divisor. Therefore, 0/3 = 0, 1/3 = .3333, 2/3 = .6666. But in this case, it also needs to be multiplied by 5. 0*5=0, .333*5=1.6666, .6666*5=3.3333.
    Then the resulting integer is added to the original result. In the above formula, I rounded it off to 1.5 or 15/10 since you get the same integer value. Now, 0*15/10=0, 1*15/10=1 and 2*15/10=3 in integer results.

    ResLow = ResLow * 5 + (a // 3 * 15 / 10)

    And Ummm, or Ohhh, duhh, oh Crap.

    Now I can see that by not considering the remainder when getting the High bit, there is 1 number that the formula doesn't work for. 39321 the result ends up as 0001:FFFF instead of 0000:FFFF. Not good.

    Thanks misk! That would have probably driven Tomasm crazy.

    See next Post.

  7. #7
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default

    Tomasm,

    Thanks to misk's question I found that there is one number out of 60,000 that that formula has a problem with.

    39321 the result ends up as 0001:FFFF instead of 0000:FFFF.

    here's a possible fix:
    Code:
    a          var  word      ' 0-60000
    result     var  word[2]   ' 32-bit result, although largest is 17-bit
     ResHigh   var  result[1]
     ResLow    var  result[0]
    
    a = 60000    ' a test number
    
    ResLow = a / 3
    if a <> 39321 then
        ResHigh = ((ResLow - 13107) >> 15) ^ 1
    else
        ResHigh = 0
    endif
    ResLow = ResLow * 5 + (a // 3 * 15 / 10)
    Not pretty, but it's works better.

    Best regards,
    &nbsp;&nbsp;&nbsp;Darrel

Similar Threads

  1. Strugling without floating point
    By pjsmith in forum mel PIC BASIC Pro
    Replies: 15
    Last Post: - 27th March 2011, 06:29
  2. Getting out of floating point
    By jcb344 in forum General
    Replies: 3
    Last Post: - 5th August 2008, 21:18
  3. Floating Point Display Problem (serial string out)
    By Cash Olsen in forum mel PIC BASIC Pro
    Replies: 0
    Last Post: - 20th December 2007, 02:03
  4. Microchip Floating Point Routines
    By Joe Rocci in forum mel PIC BASIC Pro
    Replies: 1
    Last Post: - 12th October 2006, 19:51
  5. Floating Point
    By jrudd in forum mel PIC BASIC Pro
    Replies: 0
    Last Post: - 15th May 2005, 14:19

Members who have read this thread : 1

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts