Floating point problem

This is a discussion on Floating point problem within the C Programming forums, part of the General Programming Boards category; hey i am a complete newbie to c. I am having this problem with floating points and the output is ...

  1. #1
    Registered User
    Join Date
    Jul 2007
    Posts
    9

    Floating point problem

    hey i am a complete newbie to c.


    I am having this problem with floating points and the output is producing really wired results
    I'm using gcc to compile it

    Code:
    float i=0.0;
    for(;i<=20.0;i+=0.1)
    {
    if(i==0.0 || ((int)(i*10))&#37;10==0)
    {
    printf("\n");
    printf("%5.1f ",i);
    }
    
    printf("%5.2f ",sqrt(i));
    }
    the above code is to print a table of square roots in a sort of tabled layout.
    when we start it prints 0.0 and print the list of sqrt from 0.1 to 0.9
    when 1.0 it again goes to a new line prints 1.0 as well as the sqrts from 1.0 to 1.9
    but it creates a problem in 3.0 in my machine for some reason. Please try it out.
    It's really strange

    Regards
    Last edited by greenberet; 07-13-2007 at 08:29 AM. Reason: debugging changed the code a little

  2. #2
    Woof, woof! zacs7's Avatar
    Join Date
    Mar 2007
    Location
    Australia
    Posts
    3,459
    And what strange problem is that? Care to enlighten me?

    Usually 0.0 = double, append a f on the end if you mean float, ie 0.0f

    Code:
    float i = 0.0f;
    for(; i <= 20.0f; i += 0.1)
    {
        if(i == 0.0f || ((int)(i * 10.0f))&#37;10 == 0)
            printf("\n%5.1f ",i);
    
        printf("%5.2f ", sqrt(i));
    }
    Last edited by zacs7; 07-13-2007 at 08:41 AM.

  3. #3
    and the hat of wrongness Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    32,485
    > if(i==0.0
    You can't compare floats for equality. They are approximations, which means not all (in fact most) numbers are not represented accurately, only the nearest representable value.

    What follows is that while ( 1.0 / 3.0 ) * 3.0 might be 1 (mathematically), it doesn't follow that the floating point representation of that calculation will compare equal to 1 (it might, but don't bet on it long term).

    Long sequences of calculations like "for(;i<=20.0;i+=0.1)" are especially problematic.


    Arrange your grid using integers to maintain accuracy, then convert the grid coordinate into a float to perform your calculations.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.
    I support http://www.ukip.org/ as the first necessary step to a free Europe.

  4. #4
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,299
    Simply never use a real number type as the for loop variable.
    This is how it should be written:
    Code:
    for(int i = 0; i <= 200; ++i) // i represents 'tenths'
    {
        float fi = i * 0.1f;
        if (i % 10 == 0)
            printf("\n%5.1f ", fi);
    
        printf("%5.2f ", sqrt(fi));
    }
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  5. #5
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,046
    But that assumes a C99 compiler, because you're declaring i in the for loop initialization section.

    Also, I think that perhaps the OP meant to use
    Code:
    int i;
    for(i = 0; i <= 200; ++i) // i represents 'tenths'
    {
        float fi = i * 0.1f;
        if (i &#37; 10 == 0)
            printf("\n%5.1f ", fi);
        else
            printf("%5.2f ", sqrt(fi));
    }
    and also make the 5.1 and 5.2 the same.
    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.

  6. #6
    Registered User linuxdude's Avatar
    Join Date
    Mar 2003
    Location
    Louisiana
    Posts
    926
    but you assume C99 compiler as well with the one line comment

  7. #7
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,046
    I was just copying your code. If it was my code I'd've used fsqrt() as well, since we're dealing with floats here, not doubles.

    Not to mention using single quotes for a string.
    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.

  8. #8
    Registered User
    Join Date
    Jul 2007
    Posts
    9

    thanks

    thanks for the replies. It's been real useful to know that float numbers are approximations and may give absurd results.

    I had just been going through complex XORing to swap 2 variables without using a temp.
    But when i used the same code with arrays it produced strange results.
    Code:
    int a=2,b=5;
    a^=b^=a^=b;
    
    printf("%d %d \n",a,b);
    
    int c[2]={2,5};
    
    c[0]^=c[1]^=c[0]^=c[1];
    
    printf("%d %d",c[0],c[1]);
    output
    5 2
    0 2

  9. #9
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,046
    The XOR hack to swap two numbers is probably a bad idea these days. It's tough for a compiler to optimise it. And I think it might actually be technically undefined.

    That code works just fine for me, though GCC gives a warning on the first swap line.
    Code:
    5:    a^=b^=a^=b;
    
    5 C:\path\xorhackarray.c [Warning] operation on `a' may be undefined
    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.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. For the numerical recipes in C types!
    By Smattacus in forum C Programming
    Replies: 5
    Last Post: 10-28-2008, 07:57 PM
  2. String and Floating Point Conversion Help
    By dfghjk in forum C++ Programming
    Replies: 14
    Last Post: 05-04-2008, 12:11 PM
  3. Floating point checking problem
    By ikkiutsu in forum C Programming
    Replies: 8
    Last Post: 12-03-2003, 05:35 AM
  4. Abstract class problem
    By VanJay011379 in forum C++ Programming
    Replies: 9
    Last Post: 07-31-2002, 01:30 PM
  5. Floating point faster than fixed-point
    By VirtualAce in forum A Brief History of Cprogramming.com
    Replies: 5
    Last Post: 11-08-2001, 10:34 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21