About float/double type number in range.

Rob Cliffe rob.cliffe at btinternet.com
Wed Aug 26 07:53:02 EDT 2020



On 26/08/2020 12:02, Peter J. Holzer wrote:
> On 2020-08-26 22:40:36 +1200, dn via Python-list wrote:
>> On 26/08/2020 19:58, Joel Goldstick wrote:
>>
> [...]
>> <<< Code NB Python v3.8 >>>
>> def fp_range( start:float, stop:float, step:float=1.0 )->float:
>>      """Generate a range of floating-point numbers."""
>>      if stop <= start:
>>          raise OverflowError( "RangeError: start must be less than stop" )
>>      x = start
>>      while x < stop:
>>          yield x
>>          x += step
> This is almost the same solution as I came up with, but note that this
> is not quote the same as what Joel proposed. Repeated addition is not
> the same as multiplication with floating point numbers.
To expand on this: it is because floating point numbers cannot represent 
all real numbers exactly.
Repeated addition of a number represented inexactly will drift away from 
the mathematical value.
Example: fp_range(0, 70, 0.07) as written above will yield 1001 numbers 
ending with 69.99999999999966 (i.e. approximately, but not quite, 70).
Whereas Peter's version (below) will correctly yield 1000 numbers ending 
with 69.93.
(Even then some numbers are not represented exactly, e.g. the 
last-but-one is 69.86000000000001.)

>   
>
> A generator based on Joel's idea would look like this:
>
> def fp_range(start, end, step):
>      v = start
>      n = int(math.ceil((end - start) / step))
>      for i in range(n):
>          yield start + i * step
>



More information about the Python-list mailing list