Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Finding the smallest integer that can not be represented as an IEEE-754 32 bit float [duplicate]

Possible Duplicate:
Which is the first integer that an IEEE 754 float is incapable of representing exactly?

Firstly, this IS a homework question, just to clear this up immediately. I'm not looking for a spoon fed solution of course, just maybe a little pointer to the right direction.

So, my task is to find the smallest positive integer that can not be represented as an IEEE-754 float (32 bit). I know that testing for equality on something like "5 == 5.00000000001" will fail, so I thought I'd simply loop over all the numbers and test for that in this fashion:

int main(int argc, char **argv)
{
    unsigned int i; /* Loop counter. No need to inizialize here. */

    /* Header output */
    printf("IEEE floating point rounding failure detection\n\n");

    /* Main program processing */
    /* Loop over every integer number */
    for (i = 0;; ++i)
    {
        float result = (float)i;

        /* TODO: Break condition for integer wrapping */

        /* Test integer representation against the IEEE-754 representation */
        if (result != i)
            break; /* Break the loop here */
    }

    /* Result output */
    printf("The smallest integer that can not be precisely represented as IEEE-754"
           " is:\n\t%d", i);


    return 0;
}

This failed. Then I tried to subtract the integer "i" from the floating point "result" that is "i" hoping to achieve something of a "0.000000002" that I could try and detect, which failed, too.

Can someone point me out a property of floating points that I can rely on to get the desired break condition?

-------------------- Update below ---------------

Thanks for help on this one! I learned multiple things here:

  1. My original thought was indeed correct and determined the result on the machine it was intended to be run on (Solaris 10, 32 bit), yet failed to work on my Linux systems (64 bit and 32 bit).

  2. The changes that Hans Passant added made the program also work with my systems, there seem to be some platform differences going on here that I didn't expect,

Thanks to everyone!

like image 657
LukeN Avatar asked Oct 08 '10 11:10

LukeN


1 Answers

The problem is that your equality test is a float point test. The i variable will be converted to float first and that of course produces the same float. Convert the float back to int to get an integer equality test:

float result = (float)i;
int truncated = (int)result;
if (truncated != i) break;

If it starts with the digits 16 then you found the right one. Convert it to hex and explain why that was the one that failed for a grade bonus.

like image 192
Hans Passant Avatar answered Sep 25 '22 16:09

Hans Passant