-
Notifications
You must be signed in to change notification settings - Fork 129
Description
Describe the bug
Dividing two integer arrays (eg dtype int16) using the true division operator / returns the result of floor division converted to float, rather than the true division result.
ulab version: 6.11.0-2D-c
To Reproduce
from ulab import numpy as np
a = np.array([1, 2, 3, 4, 5], dtype=np.int16)
b = np.array([5, 4, 3, 2, 1], dtype=np.int16)
print("a/b:", a/b)
print("a/3:", a/3)
print("a/3.0:", a/3.0)Resulting behaviour
a/b: array([0.0, 0.0, 1.0, 2.0, 5.0], dtype=float32)
a/3: array([0.0, 0.0, 1.0, 1.0, 1.0], dtype=float32)
a/3.0 array([0.33333334, 0.6666667, 1.0, 1.3333334, 1.6666666], dtype=float32)Expected behavior
a/b: array([0.2, 0.5, 1.0, 2.0, 5.0], dtype=float32)
a/3: array([0.33333334, 0.6666667, 1.0, 1.3333334, 1.6666666], dtype=float32)
a/3.0: array([0.33333334, 0.6666667, 1.0, 1.3333334, 1.6666666], dtype=float32)The resulting array is of float type, which is correct for /, but the returned values are the result of integer (floor) division, converted to floats. This happens for any pair of integer type arrays, and also when dividing by an integer scalar. Dividing by a float scalar gives the expected result, as shown.
Additional context
A quick look through the source code suggests the problem lies in the BINARY_LOOP macro. This takes the passed operator / and generates the nested loops necessary to implement it. However, the resulting C code eventually executes something like <left-hand-side> / <right-hand-side>, which in C results in integer (floor) division if both operands are integer types, and floating division if either operand is a floating type. To get the right result, one or both operands needs to be cast to a floating type before applying the operator.
I would offer a code fix, but I'm very new to both ulab and micropython, and not at all sure how best to modify the code without breaking something else... :-)