views:

85

answers:

3

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!

+2  A: 

I think you should reason on the representation of the floating numbers as (base, sign,significand,exponent)

Here it is an excerpt from Wikipedia that can give you a clue:

A given format comprises:

* Finite numbers, which may be either base 2 (binary) or base 10

(decimal). Each finite number is most simply described by three integers: s= a sign (zero or one), c= a significand (or 'coefficient'), q= an exponent. The numerical value of a finite number is (−1)s × c × bq where b is the base (2 or 10). For example, if the sign is 1 (indicating negative), the significand is 12345, the exponent is −3, and the base is 10, then the value of the number is −12.345.

Luca Martini
+2  A: 

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.

Hans Passant
Thanks! This did the trick and I'm happy that my original idea prooved to be valid :)
LukeN
A: 

That would be FLT_MAX+1. See float.h.

Edit: or actually not. Check the modf() function in math.h

Let_Me_Be
No. Have you tried it?
Hans Passant
@Hans Yeah, there are definitely smaller numbers that can't be represented.
Let_Me_Be
Instead try `(1<<FLT_MANT_DIG)+1`.
R..