The reason is that you can't represent all numbers exact with floating point objects. You have to approximate the number because you have a limited number of bits. The str() function does some pretty printing of float numbers (that includes some rounding). If you print the exponential version you see what happens.
Look at the following code
def extractDecimals(num):
try:
if(num > int(num)):
decimals = num - int(num)
while(decimals > int(decimals)):
print 'decimal: ' + str(decimals), '%.20e' % decimals
print 'int: ' + str(int(decimals))
if int(decimals)!=int(decimals+EPSILON):
decimals += EPSILON
break
decimals *= 10
decimals = int(decimals)
return decimals
else:
raise DecimalError(num)
except DecimalError, e:
e.printErrorMessage()
The output for the number 1.988 is
decimal: 0.988 9.87999999999999990000e-001
int: 0
decimal: 9.88 9.87999999999999900000e+000
int: 9
decimal: 98.8 9.87999999999999830000e+001
int: 98
decimal: 988.0 9.87999999999999770000e+002
int: 987
Result: 988
You have to determine if the number after the decimal point is close to 1.0. The number 0.9999999999999.... is mathematically equal to 1.0.
That is why I use an EPSILON value of 1E-10