I think you are misunderstanding what @Bimbam and @cybereality are trying to explain. The issue is that, for any float, there is always going to be precision issues. This is the 9th+ digit that @BimBam was explaining in their post. For any float value, no matter what you assign it to, there is going to be precision issues that utlimately look like noise on the fringes of the number. This issue is compounded the larger (like 1000000+
) or smaller (0.00000001
) you go, as you consume more digits.
So, to answer the consistency problem: GDScript is a interpreted, dynamically typed language. Because of this, it likely defaults to floats first when using numbers. This is for simplicity, and also because then if you add a fraction of a number to it, it doesn't need to do any conversion and can just instantly add the numbers together. For most GDScript functions, the code likely takes the float precision issue into account. The find
function appears to be a function that does not take this into account, leading to the issue.
Likely how the find
function works is that it uses a hash and compares hash values. This is because arrays/lists in GDScript can contain any value, requiring a find
function that can find any value, no matter what it might be. My guess is that by using the hash for each variable, it can work with all of the built-in types (string, int, float, bool, etc) and work with Godot's Varient type, allowing it to work with practically everything custom in Godot. However, the precision issue makes two floats, even both assigned to 1, have a different hash, leading to the issue. This is not the case with 1.0 == 1
, as the code here does a value comparison rather than a hash one.
There are a few potential ways to adapt the code to work around this behavior though! I'm not positive the first method will work, but I know the second one should.
Method 1: Explicitly make the number you put into the array an integer:
var arr : Array = []
for i in 3:
arr.append(int(i))
print (arr)
print (arr.find(1))
Or, potentially:
var arr : Array = []
for i in 3:
# It should default to an int in this case
arr.append(i)
print (arr)
print (arr.find(1))
Method 2: Write a custom find function
The find function is really simple, honestly, so it should be easy enough to write a find function that looks for the passed in integer:
func _ready():
var arr : Array = []
for i in 3:
arr.append(float(i))
print (arr)
print(int_find(arr, 1))
func int_find(array, value):
# Make sure the value passed is an integer
if not value is int:
return -1
# go through each element in the array
for i in range(0, array.size()):
# only floats and strings can be converted
if array[i] is float or array[i] is string:
if int(array[i]) == value:
return i
return -1
Question: why in the code example are you using arr.append(float(i))
if you want to compare using integers? You are explicitly telling Godot to store the value as a float, but if you are only storing integers, why not just let Godot handle the type conversion by using code like arr.append(i)
?