Thread: float number division

  1. #1
    Registered User
    Join Date
    Jan 2009
    Posts
    2

    Question float number division

    Hi guys,

    does anyone know how to lose the small noise getting added to float numbers?

    here is the code:

    Code:
    typedef unsigned long u32;
    
    int main()
    {
        float width,left;
        float temp1, temp2;
        u32 x;
    
        temp1 = 640.0;
        temp2 = 800.0;
    
        width = (temp1 / temp2);
    
        left = -(width / 2);
    
        x = (left + 0.5f) * 800;
    
        printf("width = %f\n",width);
        printf("left = %f\n",left);
    
        printf("x = %d\n", x);
    
        return 0;
    }
    if you punch the numbers on your calculator, the answer is 80 which is correct.
    This piece of code however, shows 79.

    This is because the var "width" contains very small noise after the first division. It prints out 0.8 but the actual value is 0.800000012.

    Is there any way to get rid of the 12 at the end?
    Last edited by hoistyler; 01-13-2009 at 07:40 PM. Reason: loose -> lose.. thanks to tabstop :)

  2. #2
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    If you wanted to "lose the noise" like your calculator does, you would probably have to do it the way your calculator does it: keep track of everything digit by digit, and perform all calculations digit by digit (as opposed to using binary).

    Or, if you just want an integer back (since you are storing in an integer), you could just round.

  3. #3
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    You could just ask printf() to only print a few significant digits.
    Code:
    printf("%.4f", width);
    I'm not sure if that's what you're asking.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  4. #4
    Registered User
    Join Date
    Jan 2009
    Posts
    2
    Thanks for reply dwks but how it prints out was not my concern. I was working with pixel coords and the result was sometimes 1 pixel off just like in the example I posted.
    I guess the best option is what tabstop suggested(rounding). Thanks to tabstop.
    But was this always an underlying problem in float/double number operations? I never realised.

  5. #5
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by tabstop View Post
    If you wanted to "lose the noise" like your calculator does, you would probably have to do it the way your calculator does it: keep track of everything digit by digit, and perform all calculations digit by digit (as opposed to using binary).
    Binary isn't made of digits?
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  6. #6
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by brewbuck View Post
    Binary isn't made of digits?
    No it's made of bits.

    Okay I should have specified base-10 digits.

  7. #7
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    First of all, for both calculators and computers, most floating point calculation are not EXACT. Calculators often "cheat" and calculate one more digit than they show, which is used to round off the number - you can prove this by typing in 0.333... with as many 3's as the calculator can use, and multiply by 3. Then try the same thing by calculating 1/3 and then multiply by 3. Some calculators are "more precise" in the second case and come up with 1.0, rather than 0.99999...

    One solution for your calculation here would be to round the final number, e.g:
    Code:
    x = ((left + 0.5f) * 800.0 + 0.5);
    Alternatively, you may get better results using "double" - float is about half the precision, and for most things, the calculation time for float or double is identical [at least in x86 processors, where the all intermediate calculations are done to 80-bit precision, and the result is only rounded down to 32 bits when it is actually stored as a float - when that happens depends on the optimization level, the complexity of the calculation and the compiler itself].


    And finally, the 0.800000012 is probably more of a calculation artifact when translating the number into decimal, rather than the fact that it is "slightly larger than it should be".

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Promblem with code
    By watchdogger in forum C Programming
    Replies: 18
    Last Post: 01-31-2009, 06:36 PM
  2. Replies: 14
    Last Post: 06-28-2006, 01:58 AM
  3. error declaration terminated incorrectly help
    By belfour in forum C++ Programming
    Replies: 7
    Last Post: 11-25-2002, 09:07 PM
  4. ~ Array Help ~
    By Halo in forum C++ Programming
    Replies: 1
    Last Post: 11-08-2002, 04:19 PM
  5. Newton-Raphson number squaring method/pointers
    By inakappeh in forum C Programming
    Replies: 2
    Last Post: 08-29-2001, 11:04 AM

Tags for this Thread