Confuse about the natural of integer and float

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

The requirement is quite simple, I want something to happen when an interval number could be divided by whole (without decimal). However, the behaviour is not very straight forward. If use INT number, it return an INT ignoring the decimal. If I put float(), the outcome is identified as a float. I thought the INT and FLOAT are used to identify data types, but now it all mix up, INT is float and float is been recognised as an INT.

How could I achieve this function that if value is 18, and 18/5 = 3.6, 3.6 is not an INT(currently it will return 3 as INT). When value is 20, 20/5 = 4, 4 is an INT and something happen? Thank you.

My function code is not working, since INT and FLOAT could not be identified.

func set_rewards(value):
   var score = 5
   var reward = value/float(score) 
   if typeof(reward) == TYPE_INT:
	  print("I am INT")
func set_rewards(value: float) -> void: # this makes value float
	var score := 5.0 # this makes score float
	var reward := value / score

rakkarage | 2020-07-19 01:59

:bust_in_silhouette: Reply From: jgodfrey

The result of dividing two INT values is always an INT. This is common an many languages and environments. To get a float result, you need to ensure that at least one value used in the expression is, itself, a float. You can do that in a number of ways, including:

print(18 / 5)        # int divided by int is an int (3)
print(18.0 / 5)      # float divided by int is a float (3.6)
print(18 / 5.0)      # int divided by float is a float (3.6)
print(float(18) / 5) # promote int 18 to float and then divide (3.6)

Thank you for your reply, the problem for me now is that, if I use a float in the calculation, the return result is identified as a float number, so even 20/5.0 = 4.0 that way my intention of if answer is qual to an INT will never work. Is that a way the system could recognised the data type of the result automatically? something like if 18/5 = 3.6 INT false, 20/5 = 4 INT true? Thank you.

Idleman | 2020-07-19 01:59

You’ll probably need to come up with a clever way to figure this out. If I were doing it, I’d probably convert the value in question to both an int and a float and then compare that the two values are “sufficiently close” to the same. If they are, the original value can be considered an int.

Here’s one example of doing just that. I’d guess something like this will work for you:

func _ready():
	print(is_int(3.0))     # prints "true"
	print(is_int(3))       # prints "true"
	print(is_int(3.0001))  # prints "false"

func is_int(val):
   return(is_equal_approx(float(val), int(val)))

jgodfrey | 2020-07-19 16:54

Hadn’t noticed you already had an accepted answer here… Take the above as “another option”… ;^)

jgodfrey | 2020-07-19 17:38

:bust_in_silhouette: Reply From: JimArtificer

It looks like you will want to use the fposmod function. It will return 0 whenever the division would result in an integer. You can use the function’s result to branch your logic. Consider also looking at the fmod function.

Alternatively, you could consider storing everything as float variables to eliminate the confusion you are experiencing. The engine itself uses floats in a lot of places where integers would make more sense.

Thank you for your suggestion, and it works. I have read the document about fposmod and fmod but frankly not really sure why and how they work, but somehow it gives the result.

Idleman | 2020-07-19 07:27