Floating point analysis, why do these lines differ?

Discussion in 'Mac Programming' started by atszyman, May 24, 2005.

  1. atszyman macrumors 68020

    atszyman

    Joined:
    Sep 16, 2003
    Location:
    The Dallas 'burbs
    #1
    I'm working on a homework problem that requires me to do some floating point operations to illustrate the possible problems in assuming that floating point numbers are always completely accurate. I have the quoted program written and have managed to prove to myself that OS X does not use IEEE 754 floating point format. What format does it use?

    Also in the second while loop, the printf lines end up differing in their output [also quoted] despite being mathematically equivalent. Any ideas why?

     
  2. wiseguy27 macrumors 6502

    wiseguy27

    Joined:
    Apr 30, 2005
    Location:
    USA
    #2
    Why would you assume that Mac OS X doesn't use IEEE 754??? On the contrary, it does use IEEE 754 (do a search for it on http://developer.apple.com).

    You also have to keep in mind that C/C++ by default promotes floats to doubles in all operations (and truncates them back to float on assignment). This would happen in all your addition statements and the printf calls. If you want to prevent the automatic conversion to double, then you would have to use an explicit cast in each statement, like "(float)eps".
     
  3. atszyman thread starter macrumors 68020

    atszyman

    Joined:
    Sep 16, 2003
    Location:
    The Dallas 'burbs
    #3
    I did do searches via Google, and Apple's websites and could not seem to find a nice direct answer where I was looking. Of course now that you have answered my question the results I would have liked to find hours ago pop up nicely in my searches. Why is it that I can always manage to find the answer to my questions easily once someone else points out the obvious answer that I could not previously find?

    I did not look as though it was using IEEE 754 because when I printed the data in hex format it appeared that the exponents were not lining up with were they should be for a proper IEEE 754 floating point number. However they do line up with the correct place for a double precision floating point number. Which would explain everything.

    The automatic promotion by C/C++ explains the results that I was seeing.

    Thank you for your help.
     
  4. atszyman thread starter macrumors 68020

    atszyman

    Joined:
    Sep 16, 2003
    Location:
    The Dallas 'burbs
    #4
    Ok, things make a little more sense now but if I modify the first while loop to :

    while ((float)eps != 0.0)
    {
    printf("After step %d, eps equals : %x\n", step, (float)eps);
    eps = eps/2.0;
    step+=1;
    }


    I get these as the hex values out:

    After step 1, eps equals : 3ff00000
    After step 2, eps equals : 3fe00000
    After step 3, eps equals : 3fd00000
    After step 4, eps equals : 3fc00000
    After step 5, eps equals : 3fb00000
    After step 6, eps equals : 3fa00000
    .
    .
    .

    As you can see the exponent bits which should occupy bits 30:23 are actually occupying 30:20 which matches for double precision. Is there any way to get the single precision values out?

    Thanks again, in advance, for answering what will probably turn out to be another blatantly obvious question.
     
  5. wiseguy27 macrumors 6502

    wiseguy27

    Joined:
    Apr 30, 2005
    Location:
    USA
    #5
    unions?

    Ok, this took a few minutes. I haven't yet figured out why, but the printf you're doing with the cast to the float is not working. Your float variables are fine as they are - the problem in your program is only with the printf where the float still gets promoted to double.

    When you see tricky problems like this, the first thing you ought to do is turn on all warnings during compilation - this is done by using the '-Wall' command line option in gcc (which I presume you're using) - for example, 'gcc -Wall test.c'. If you do this, you see a warning about "format %x expects 'unsigned int', but argument 3 has type 'double'" - this occurs with the (float) cast in the printf!

    When you wish to interpret bit patterns in hexadecimal (or byte format), it is better to match the basic integer type - what I mean by this is that when you attempt to use a '%x' for printf, the best argument would be an unsigned int (as the warning above indicated). Now the question is, how would you get a floating point number in an unsigned int without truncation? Use a union!

    Declare something like
    union floatint
    {
    float f;
    unsigned int i;
    };

    and declare a variable like
    union floatint fi;

    Before your printf, do this:
    fi.f = eps;
    Here, you're assigning the value of eps into the float variable f. Since f is part of a union, it can also be reinterpreted as an int using the member called i. In a union, all variables share the same memory storage - so the most common way of using unions is to assign values to some members and extract the values from the other members to interpret the same set of bits in a different way.

    In your printf, use the int part of this union instead of using eps, like:
    printf("step %d, eps = %x\n",step,fi.i);

    Viola! You have good results now! :)

    Note: Although this has temporarily solved your problem, I would recommend digging into the manual for gcc to find out why the automatic promotion occurs even with a cast.
     
  6. wiseguy27 macrumors 6502

    wiseguy27

    Joined:
    Apr 30, 2005
    Location:
    USA
    #6
    Maybe Google is not the only answer for search. :p Try using other search engines when you don't get optimum results from one of them. You could try Teoma (www.teoma.com), Yahoo (www.yahoo.com), Clusty (www.clusty.com) and many more. But the most important thing in searches is typing the right words! :D Simple as this may sound, this is the biggest impediment that keeps people away from the results that they expect. So try different combinations of words. Searching is something you get better at with trying (and consciously trying to improve the results).
     
  7. atszyman thread starter macrumors 68020

    atszyman

    Joined:
    Sep 16, 2003
    Location:
    The Dallas 'burbs
    #7
    Trust me, 99% of the time I get my searches right. It usually only takes me a couple of minutes to find just about anything I am looking for on the web. Last night was one of the few exceptions, possibly due to my hiatus from programming and the fact that my daughter wasn't sleeping which was just leading to frustration all around.

    I will probably be posting on this board for the next 12 weeks since my current class will require more programming from me than I have done in a long time. I will from this point on preface my posts with "I have searched..." or "I have not had time to search, but could someone please help with..." so that the searching portion can be clarified up front.

    Thank you for your help thus far.
     
  8. wiseguy27 macrumors 6502

    wiseguy27

    Joined:
    Apr 30, 2005
    Location:
    USA
    #8
    LOL. It's not a big deal at all. We very well know that searching doesn't always show us the results because we may not know what exactly to search for. At other times it's also a question of the words and the search engine itself (I believe most of them are good, and that's one of the reasons I don't use Google at all).

    Asking questions without searching is a natural thing that people do - it saves a lot of time for many! So unless it's "too dumb" a question (the definition of which is subjective), it's fine to post "newbie like" questions. One of the things I have learned is that responding properly to questions also enhances ones knowledge (and also reminds one that the brain is not as rusty as one might assume it to be). :D

    Let me know how the solution with "union" went (and if you found something else related to gcc - this is definitely a compiler issue).
     
  9. atszyman thread starter macrumors 68020

    atszyman

    Joined:
    Sep 16, 2003
    Location:
    The Dallas 'burbs
    #9
    The union trick worked very well. The hex value now behaves exactly like I would expect (not that it is necessary for the homework problem but it was bugging me).

    Thanks for your help.
     

Share This Page