Array.has() method return false when value is in and strange float decimal

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By BigBadWouf

Hello.

I have two questions.

  1. I have a Vector3 variable containing a position, and another Array variable containing many Vector3. For example, i call first variable “position” and second “grid”. These contains :
(-2.5, 0, -2.5)

and :

[(-1.5, 0, -3.5), (-3.5, 0, -3.5), (-2.5, 0, -2.5), (-2.5, 0, -4.5)]

But :

grid.has(position)
position in grid

Return False. This is real data in my console.
The Vector3 is in the Array, so why False ?

  1. To produce the grid variable, i use something like that:
allowed_in_out.append(xform.origin + (xform.basis.x * 1))
allowed_in_out.append(xform.origin + (xform.basis.x * -1))
allowed_in_out.append(xform.origin + (xform.basis.z * 1))
allowed_in_out.append(xform.origin + (xform.basis.z * -1))

The result is always float .5, but sometimes, that make a strange float like :
2.499999 or 2.500001

I’m sure the entry data is correct. So, how to avoid this ?

:bust_in_silhouette: Reply From: jgodfrey

I’m not sure how the array has method works under the covers, but I assume it’s being tripped up by trying to do an equality check on a floating point value (in this case) - which is likely to fail randomly.

While there might be a better way, the Vector3 datatype has a is_equal_approx ( Vector3 v ) method that’s designed to return true when 2 Vector3 values are approximately equal. You could certainly write your own function that accepts a candidate Vector3 and then iterates through your Vector3 array checking each member via is_equal_approx to get what your after…

Here’s a rough example of what I mentioned above…

func _ready():
	var a = []
	a.append(Vector3(1.0, 1.0, 1.0))
	a.append(Vector3(1.5, 1.5, 1.5))
	a.append(Vector3(2.00001, 2.00001, 2.00001))
	print(vec3_array_has(a, Vector3(2,2,2)))

func vec3_array_has(vec3_arr: Array, vec3: Vector3) -> bool:
	for v in vec3_arr:
		v = v as Vector3
		if v.is_equal_approx(vec3):
			return true
	return false

jgodfrey | 2022-02-06 23:06

It’s exactly what i’m doing now.
That work well.
But i’m curious to know why sometime it product this stranges float.
Anyway, thank you very much for answer, explanations and example.

BigBadWouf | 2022-02-06 23:42