on floating-point numbers

Hope Rouselle hrouselle at jevedi.com
Sat Sep 4 13:32:55 EDT 2021


Hope Rouselle <hrouselle at jevedi.com> writes:

> Greg Ewing <greg.ewing at canterbury.ac.nz> writes:
>
>> On 5/09/21 2:42 am, Hope Rouselle wrote:
>>> Here's what I did on this case.  The REPL is telling me that
>>>    7.23 = 2035064081618043/281474976710656
>>
>> If 7.23 were exactly representable, you would have got
>> 723/1000.
>>
>> Contrast this with something that *is* exactly representable:
>>
>>>>> 7.875.as_integer_ratio()
>> (63, 8)
>>
>> and observe that 7875/1000 == 63/8:
>>
>>>>> from fractions import Fraction
>>>>> Fraction(7875,1000)
>> Fraction(63, 8)
>>
>> In general, to find out whether a decimal number is exactly
>> representable in binary, represent it as a ratio of integers
>> where the denominator is a power of 10, reduce that to lowest
>> terms, and compare with the result of as_integer_ratio().
>
> That makes perfect sense and answers my question.  I appreciate it.

Here's my homework in high-precision.  Thoughts?  Thank you!

--8<---------------cut here---------------start------------->8---
def is_representable(s):
  return in_lowest_terms(rat_power_of_10(s)) == float(s).as_integer_ratio()

# >>> is_representable("1.5")
# True
# 
# >>> is_representable("0.1")
# False

def rat_power_of_10(s):
  """I assume s is a numeric string in the format <int>.<frac>"""
  if "." not in s:
    return int(s), 1
  integral, fractional = s.split(".")
  return int(integral + fractional), 10**(len(fractional))

# >>> rat_power_of_10("72.100")
# (72100, 1000)

def in_lowest_terms(rat):
  from math import gcd
  n, d = rat
  return n//gcd(n, d),  d//gcd(n, d)

# >>> in_lowest_terms( (72100, 1000) )
# (721, 10)
--8<---------------cut here---------------end--------------->8---


More information about the Python-list mailing list