Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Casting to int and floating point errors?

myInt = int( 5 * myRandom() )

myRandom() is a randomly generated float, which should be 0.2.

So this statement should evaluate to be 1.

My question: is it possible that due to a floating point error it will NOT evaluate to 1?

For example if due to a floating point error something which should be 0.2 could that be LESS than that? IE, for instance consider the following 3 possibilities:

int(5 * 0.2 )                = 1 //case 1 normal
int(5 * 0.2000000000000001 ) = 1 //case 2 slightly larger, its OK
int(5 * 0.1999999999999999 ) = 0 //case 3 negative, is NOT OK, as int() floors it

Is case3 even possible?, with 0.1999999999999999 be a result of a floating point error? I have never actually seen a negative epsilon so far, only case 2, when its a slightly bit larger, and thats OK, as when it is cast to int(), that 'floors' it to the correct result. However with a negative epsilon the 'flooring' effect will make the resulting 0.9999999999999996 evaluate to 0.

like image 619
Martin K Avatar asked Jul 05 '12 19:07

Martin K


2 Answers

It is impossible for myRandom to return .2 because .2 is not representable as a float or a double, assuming your target system is using the IEEE 754 binary floating-point standard, which is overwhelmingly the default.

If myRandom() returns the representable number nearest .2, then myInt will be 1, because the number nearest .2 representable as a float is slightly greater than .2 (it is 0.20000000298023223876953125), and so is the nearest representable double (0.20000000000000001110223024625156540423631668090820312).

In other cases, this will not be true. E.g., the nearest double to .6 is 0.59999999999999997779553950749686919152736663818359375, so myInt will be 2, not 3.

like image 169
Eric Postpischil Avatar answered Oct 19 '22 20:10

Eric Postpischil


Yes, it's possible, at least as far as the C standard is concerned.

The value 0.2 cannot be represented exactly in a binary floating-point format. The value returned by myRandom() will therefore be either slightly below, or slightly above, the mathematical value 0.2. The C standard permits either result.

Now it may well be that IEEE semantics only permit the result to be slightly greater than 0.2 -- but the C standard doesn't require IEEE semantics. And that's assuming that the result is derived as exactly as possible from the value 0.2. If the value is generated from a series of floating-point operations, each of which can introduce a small error, it could easily be either less than or greater than 0.2.

like image 21
Keith Thompson Avatar answered Oct 19 '22 20:10

Keith Thompson