Reputation: 7596
While I was messing around with Python,
>>> [attr for attr in dir(1) if not attr.startswith('_')]
['bit_length', 'conjugate', 'denominator', 'imag', 'numerator', 'real']
>>> [attr for attr in dir(1.1) if not attr.startswith('_')]
['as_integer_ratio', 'conjugate', 'fromhex', 'hex', 'imag', 'is_integer', 'real']
Although I understand that 'conjugate', 'imag', and 'real' are there for the sake of compatibility with complex type, I can't understand why 'numerator' and 'denominator' exists for int only, and doesn't for a float.
Any explanation for that ?
Upvotes: 5
Views: 684
Reputation: 3911
This is most likely because floats are somewhat lossy - they can not perfectly represent every value. Consider this example:
>>> 1.0/5.0
0.20000000000000001
If you wanted the access the denominator of 1.0/5.0
python would have to return 18014398509481984
(20000000000000001/100000000000000000 == 3602879701896397/18014398509481984
). The loss of precision will cause python to have no choice but to return crazy values, so the designers chose not to implement the function.
Upvotes: 5
Reputation: 113975
This is because int
is a subclass of rational
, and float
is not. Since rational
has a denominator attribute, int
inherited it.
You can read more here
Upvotes: 2
Reputation: 1889
Take a look at the number class hierarchy: Python numbers
numbers.Integral
is a sub class of numbers.Rational
It's numbers.Rational that adds the numerator and denominator members.
Upvotes: 5