Floating point - please enlighten me!


Closed Thread
Results 1 to 16 of 16
  1. #1
    Join Date
    Mar 2009
    Posts
    653

    Default Floating point - please enlighten me!

    Ok, I came into PIC not knowing much at all (still don't - but I can sit transfixed at example programs like an lethargic lizard warming its blood on a rock for hours!!), so it should be of no surprise I don't know much about floating point....but it's becoming rapidly apparent that most of the stuff I've an interest in erhmm kinda needs it - now I know there are a few tips & tricks/workarounds, but just so I'm clear what the issue is....

    Is poor floating point a limitation .....

    a) of PBP

    or

    b) the PIC range of processorors themselves?

    If the former (a)....and you were faced with doing a lot of stuff where floating point would be a blessing - what path would you take?!!!

    If the latter (b)....what's a good option to explore with respect to other variants?

    Many thanks.
    Last edited by HankMcSpank; - 2nd October 2010 at 17:07.

  2. #2
    Join Date
    May 2004
    Location
    NW France
    Posts
    3,648


    Did you find this post helpful? Yes | No

    Wink

    Quote Originally Posted by HankMcSpank View Post
    Is poor floating point a limitation .....

    a) of PBP

    or

    b) the PIC range of processorors themselves?
    .
    Hi, Hank

    Floating point calculations need room and therefore time ... that's one sure point.

    We have to admit ... aheum ... Calculations are not something PBP has particularly developped, ( do not strike on the head ...) as it's most of time to be preferably done via .asm ( did you see PBP floating point support on melab's site ??? )

    Also remember PBP only recently introduced the 32 bits calculations with the 18F series, ...

    Well, how to tell it ... it's not the best compiler for mathematical calculations ... and , Honestly ...

    you should turn to more powerful chips ( did I say 16 or 32 bits ??? ) if you really want to calculate in such a way ...

    Is it really necessary ??? ... Always ze good question ...

    Alain
    ************************************************** ***********************
    Why insist on using 32 Bits when you're not even able to deal with the first 8 ones ??? ehhhhhh ...
    ************************************************** ***********************
    IF there is the word "Problem" in your question ...
    certainly the answer is " RTFM " or " RTFDataSheet " !!!
    *****************************************

  3. #3
    Join Date
    Nov 2003
    Location
    Wellton, U.S.A.
    Posts
    5,924


    Did you find this post helpful? Yes | No

    Default

    I have never used them, maybe they are OK.
    http://www.awce.com/compare.htm
    Dave
    Always wear safety glasses while programming.

  4. #4
    Join Date
    Nov 2005
    Location
    Bombay, India
    Posts
    966


    Did you find this post helpful? Yes | No

    Default

    Floating point is a limitation of the PBP compiler. Nothing to do with PICs in general. You can use a floating point library and get by, but the question is do you really really need it? Most times, you will be using compile time fractions which can be broken down into simple integer operations.

    The most general work around is to find an equivalent fraction that can be represented in integer math. For example, if you need to do pi x d, you can do

    (d * 22)/7 to get a value in integers
    or
    (d*220)/7 to get a value with 1 decimal place. Only now, you need to place the decimal point while displaying the value.

    I use an utility called MISCEL from http://www.miscel.dk which allows you to compute integer equivalents of a fraction in various word sizes.

    The liabilities of Floating Point
    1 - Bulky code
    2 - Very time intensive computing A single operation can take approx 2-300mS
    3 - PBP does not support it

    Of course, even the long support needs you to migrate your code to an 18F series

  5. #5
    Join Date
    Feb 2006
    Location
    Gilroy, CA
    Posts
    1,530


    Did you find this post helpful? Yes | No

    Default

    What everyone else said.

    Most C languages for PIC18 devices let you do 32 bit floats. So it is not that PICs can't do it. But these do bloat your code, and slow your calculations. Same is true for the work arounds for PBP http://melabs.com/resources/fp.htm

    The happy medium is to determine what you really need, vs what you want. The limitation of PBP just makes you think a little harder about how to work through a problem, and be the most efficient.

    About 90% of the time a member has said they needed it, I have seen their need disproved by other members on the forum. I have even been there myself. I thought I needed it to calculate the distance between two gps waypoints. Then I found there was a work around. It turned out the cordic equation (in assembly) can be about 90 times faster than math(h).

    Then there is N-bit math. I have not had a chance to use that yet, but they do look very cool. http://www.picbasic.co.uk/forum/cont...153-N-Bit_MATH
    Last edited by ScaleRobotics; - 3rd October 2010 at 05:24.
    http://www.scalerobotics.com

  6. #6
    Join Date
    Nov 2010
    Posts
    8


    Did you find this post helpful? Yes | No

    Question More Floating Point Help

    Hello

    Trying to use some floating point.

    PIC16f886

    I have tried it several ways by no real luck

    I have an number that need to be mulitiplied by .2235 to get corrrect result

    Result can be rounded back to integer

    For example

    number = 250 usually a varriable but have tried it this way for testing

    I have tried

    number * .2235 ( won't compile)

    and

    number * (1000/4474) Compiles but result is zero

    Answer should be somewhere around 55.8

    I am not sure if the math is not working or I can not just see the number

    That is; once the number is computed it is sent out RS232, it would work best if it was a whole number between 0-255 at time of sending
    in this case 56 would be great.

    Not sure where the problem lies.

    Should the math be working ?

    Is so how do I round to a whole number ?

    thanks

    Mark




    Quote Originally Posted by mackrackit View Post
    I have never used them, maybe they are OK.
    http://www.awce.com/compare.htm

  7. #7
    Join Date
    Sep 2009
    Posts
    755


    Did you find this post helpful? Yes | No

    Default

    Try to use DIV32.
    Code:
    Dummy VAR WORD
    Number VAR BYTE
    Result VAR BYTE
    Dummy = Number * 1000
    Result=DIV32 4474

  8. #8
    Join Date
    Oct 2005
    Location
    Loveland CO USA
    Posts
    83


    Did you find this post helpful? Yes | No

    Default

    Not using a compiler, using a calculator.
    Input=250 and you want about 1/4 of that.
    250*.2235=55.875
    With out using a decimal point!
    250*223/1000=55.75 (I did not use 2235/10000)
    If the input will fit into a byte and 223 fits into a byte. Then (byte * byte)=word and then word/1000=55.
    If you need a input like 350 which is a word and/or you want to use 2235/10000 then you will need to do word*word and word**word to get two words or 32 bits. You might also look at word*/word to get 16 bits out of the middle of the 32 bits.

  9. #9
    Join Date
    Nov 2010
    Posts
    8


    Did you find this post helpful? Yes | No

    Thumbs down WOW ! Thats Smart

    Not using a compiler, using a calculator.
    Input=250 and you want about 1/4 of that.
    250*.2235=55.875
    With out using a decimal point!

    Yes, I always like the types of Stupid answer's one gets when asking a simple question.

    Number is a variable and constantly changing.

    As I said for example 250

    This is just part of a longer calculation. If it was as simple as just putting a number I really wanted, I think I might of though of that....

    I was just looking for the format to input numbers like .00044

    thanks

    Quote Originally Posted by ronsimpson View Post
    Not using a compiler, using a calculator.
    Input=250 and you want about 1/4 of that.
    250*.2235=55.875
    With out using a decimal point!
    250*223/1000=55.75 (I did not use 2235/10000)
    If the input will fit into a byte and 223 fits into a byte. Then (byte * byte)=word and then word/1000=55.
    If you need a input like 350 which is a word and/or you want to use 2235/10000 then you will need to do word*word and word**word to get two words or 32 bits. You might also look at word*/word to get 16 bits out of the middle of the 32 bits.

  10. #10
    Join Date
    Nov 2010
    Posts
    8


    Did you find this post helpful? Yes | No

    Thumbs up Thanks I will give it a try, have a few questions though.

    Quote Originally Posted by pedja089 View Post
    Try to use DIV32.
    Code:
    Dummy VAR WORD
    Number VAR BYTE
    Result VAR BYTE
    Dummy = Number * 1000
    Result=DIV32 4474
    Make sure I have this right.

    By defineing Result at a byte, this will round the result to byte lenght ?

    Lets say I need a decimal like .0004
    Would I need several lines of code or can I just use

    Dec1 VAR WORD
    Result VAR BYTE
    Something VAR WORD

    Dec1=1/2500 'this should be .0004 ' will this work ? or need DIV32
    Result = Something * Dec1 ' something being between 0 and 500

    Result is now rounded ?

    Do I alway need a DIV32 when a want a decimal result ?

  11. #11
    Join Date
    Aug 2010
    Location
    Maryland, USA
    Posts
    869


    Did you find this post helpful? Yes | No

    Default

    Gee, and you question SO looked like you needed to multiply a whole number by .2235 and the .2235 was where the trouble is. If you need .00044*.2235, thats a different problem. You are correct, your question was simplified.Where are you getting numbers like .00044 in your pic? how is that generated?
    -Bert

    The glass is not half full or half empty, Its twice as big as needed for the job!

    http://foamcasualty.com/ - Warbird R/C scratch building with foam!

  12. #12
    Join Date
    Nov 2003
    Location
    Greece
    Posts
    4,115


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by mark30504 View Post
    Yes, I always like the types of Stupid answer's one gets when asking a simple question.
    Well, as was stated your question, ronsimpson did answer very good.

    A simple thank would be OK if you did no liked the time he spent for you.

    Anyway, PBP does not support FP directly. So tricks like the one suggested should be used.

    A byte is 0-255 in range and a word 0-65535, so none will store you values as is.

    Have a look at n-bit math here:

    http://www.picbasic.co.uk/forum/show...ght=n-bit+math

    or real Floating Point here:

    http://melabs.com/resources/fp.htm

    Ioannis

  13. #13
    Join Date
    Nov 2010
    Posts
    8


    Did you find this post helpful? Yes | No

    Question Just trying to learn how to use work around in PIC of Decimal values

    Quote Originally Posted by cncmachineguy View Post
    Gee, and you question SO looked like you needed to multiply a whole number by .2235 and the .2235 was where the trouble is. If you need .00044*.2235, thats a different problem. You are correct, your question was simplified.Where are you getting numbers like .00044 in your pic? how is that generated?
    Hello

    Thanks

    I am just trying to understand the work around format in PIC to work with floating point values, the systems I normally program have floating point at part of there normal stucture.

    I though from the orignal post that all you needed to do is use fractions in your formula and it would work but it does not seem to be so.

    For example If I needed to multiply some varriable by .234 or any decimal value to get an answer, how would this be done?

    In my case I am takeing a analog voltage and turning in into a tempature that is displayed on a screen.

    The temperature result does not need to be floating point

    But if I can not use floating point numbers to scale correctly the value could be off by 5+- degrees pretty quickly

    The true formula is

    result=adc10((adc10*.00034)+.2235) 'where adc10 in the pic 10 analog register

    To be within 1% of the true tempature

    Thanks

  14. #14
    Join Date
    Aug 2010
    Location
    Maryland, USA
    Posts
    869


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by mark30504 View Post
    The true formula is

    result=adc10((adc10*.00034)+.2235) 'where adc10 in the pic 10 analog register

    To be within 1% of the true tempature

    Thanks
    so plugging in extremes:
    adc10=1 gives us
    result=1((1*.00034)+.2235)=1(.00034+.2235)=1(.2238 4)=.22384
    adc10=1023 gives us
    result=1023((1023*.00034)+.2235)=1023(.34782+.2235 )=1023(.57132)=584.46036

    Is this correct? Seems like quite a lot of work to scale an answer. what temps do the extremes represent?
    -Bert

    The glass is not half full or half empty, Its twice as big as needed for the job!

    http://foamcasualty.com/ - Warbird R/C scratch building with foam!

  15. #15
    Join Date
    Nov 2003
    Location
    Wellton, U.S.A.
    Posts
    5,924


    Did you find this post helpful? Yes | No

    Default

    Back up to post #8

    The constants
    .00034
    .2235

    Would be changed to
    34
    223

    In your formula.
    Then at the end you would divide by a power of ten.
    If all of this fits into the variable type used
    BYTE
    WORD
    LONG
    then the result will be truncated to an integer.
    Truncating to an integer is what you wanted...
    Dave
    Always wear safety glasses while programming.

  16. #16
    Join Date
    Feb 2006
    Location
    Gilroy, CA
    Posts
    1,530


    Did you find this post helpful? Yes | No

    Default

    You could simplify your math to make it easier for the Picbasic commands.

    Since you have:

    Temp = ADC10 * ((ADC10 * .00034) + .2235)


    Why don't we get rid of that ugly .00034
    1/.00034 = 2941

    So we multiply both sides by 2941 ...

    Temp * 2941 = ADC10 * (ADC10 + 657)


    Then lets divide both sides by 2941 ...

    Temp = (ADC * (ADC10 + 657)) / 2941

    Then you can use div32

    Code:
    dummy = ADC10 * (ADC10 + 657)
    Temp = div32 2941
    And I think the result is close enough...
    Last edited by ScaleRobotics; - 25th November 2010 at 17:49.
    http://www.scalerobotics.com

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