Python Forum
Inclusive (closed) range with float numbers - Printable Version

+- Python Forum (https://python-forum.io)
+-- Forum: Python Coding (https://python-forum.io/forum-7.html)
+--- Forum: General Coding Help (https://python-forum.io/forum-8.html)
+--- Thread: Inclusive (closed) range with float numbers (/thread-17889.html)



Inclusive (closed) range with float numbers - mapg - Apr-27-2019

Hi

I need to add range of numbers to some arrays used, but I see that range in Python is not for float numbers and is not inclusive, namely range is not including the last number.

Seems that we need to use extra functions to complement the default function in Python.

I was able to get ranges using floats using this function:
def float_range(start, stop, skip = 1.0, decimals = 2):
	for i in range(int(start / skip), int(stop / skip)):
		yield float(('%0.' + str(decimals) + 'f') % (i * skip))

my_float_range = float_range(0.45, 0.6, 0.01)

all_combo = list(my_float_range)
print(f'size={len(all_combo)}')
pprint(all_combo)
Output:
size=15 [0.45, 0.46, 0.47, 0.48, 0.49, 0.5, 0.51, 0.52, 0.53, 0.54, 0.55, 0.56, 0.57, 0.58, 0.59] BUT I need to get in the array 0.60 too!!
I have this function to get inclusive ranges, but is not valid for float numbers
def closed_range(slices):
	slice_parts = slices.split(',')
	[start, stop, step] = map(int, slice_parts)
	num = start
	if start <= stop and step > 0:
		while num <= stop:
			yield num
			num += step
	# if negative step
	elif step < 0:
		while num >= stop:
			yield num
			num += step

all_combo = list(closed_range('1, 6, 1'))
print(f'size={len(all_combo)}')
pprint(all_combo)
Output:
size=6 [1, 2, 3, 4, 5, 6]
How can I get inclusive ranges also valid for float numbers?

Thank you very much for your reply

Mapg


RE: Inclusive (closed) range with float numbers - Yoriz - Apr-27-2019

You could call the function with the end as the next step my_float_range = float_range(0.45, 0.61, 0.01)
or alter the function to have an inclusive option.
def float_range(start, stop, skip = 1.0, decimals = 2, inclusive=True):
    if inclusive:
        stop += skip
    for i in range(int(start / skip), int(stop / skip)):
        yield float(('%0.' + str(decimals) + 'f') % (i * skip))



RE: Inclusive (closed) range with float numbers - Gribouillis - Apr-27-2019

Use
>>> import numpy as np
>>> np.linspace(0.45, 0.6, 16)
array([ 0.45,  0.46,  0.47,  0.48,  0.49,  0.5 ,  0.51,  0.52,  0.53,
        0.54,  0.55,  0.56,  0.57,  0.58,  0.59,  0.6 ])
Notice this in the documentation of numpy.arange()
numpy documentation Wrote:When using a non-integer step, such as 0.1, the results will often not
be consistent. It is better to use linspace for these cases.



RE: Inclusive (closed) range with float numbers - mapg - Apr-27-2019

Obviously, it's very practical what you mentioned. For now, it's the simplest solution.

Thanks Yoriz

(Apr-27-2019, 08:47 PM)Gribouillis Wrote: Notice this in the documentation of numpy.arange()
[quote=numpy documentation] When using a non-integer step, such as 0.1, the results will often not
be consistent. It is better to use linspace for these cases.

Yes, I am getting an extremely long float at 0.47

I am formatting all this as follows ...
import numpy as np
from numpy import linspace

myRange = list(np.linspace(0.45, 0.6, 16))
myFormattedRange = ['%.2f'% elem for elem in myRange]
Output:
print(myRange) [0.45, 0.46, 0.47000000000000003, 0.48, 0.49, 0.5, 0.51, 0.52, 0.53, 0.54, 0.55, 0.56, 0.57, 0.58, 0.59, 0.6] print(myFormattedRange) ['0.45', '0.46', '0.47', '0.48', '0.49', '0.50', '0.51', '0.52', '0.53', '0.54', '0.55', '0.56', '0.57', '0.58', '0.59', '0.60']



RE: Inclusive (closed) range with float numbers - Gribouillis - Apr-27-2019

Quote:Yes, I am getting an extremely long float at 0.47
Read this page in the python documentation. It is not a limitation of python, it is a limitation of the way computers handle floating numbers (namely the IEEE-754 format)
>>> 0.45 + 0.01 + 0.01
0.47000000000000003