route int / float question
Hello.
I need to know if a float number "is an integer"..
If I send "32" and "32.2" to [route int float]
it's working good to know what number is a float or an integer.
Here I need to route "32.0" to be recognize "as an integer"
but all other 32.xxxx has still to be routed to float
For information, I need that because I am looking for a way to know if a number is or not a multiple of, for example 3.
But maybe there is a more clever solution..
For now , I divide the number by 3 and try to route the solution between integer and float...
If it's integer it's a multiple of 3, if it's a float, it is not..
any idea ?
thank you !
A solution for this class of problems may be implemented in Max in several ways. This is something I prefere:
About this example: because of the nature of the mechanisms behind floating point arithmetic a direct comparison is not a good idea. Better to assume that the decimal part less than the threshold means that the number is an integer.
it's perfect !
thank you Yaniki !
atchoo.

=)
@Roman
I think this should work correctly, however direct comparison (of two floating point values) is often treated as a bad practice: https://bitbashing.io/comparing-floats.html
Anyway it should work, of course ;-)
it works great until 0,00001, just not for smaller numbers.^^
of course my suggestion is only a compromise, too. while 0 int and 0 float are actually no problem, the float to int conversion of the int() operator is.
i am a bit biased here because i use 32 bit max, and in 32 bit there is no real danger to use $f1 besides of int($f1), because both are converted to a 64 bit float value inside expr. and you can be sure that it is the same value.
... i think. :D
what i mean is, mine might also be not perfect for up to an exponent of -380, but it will be perfect for the number precision you can and want to type into objects usually.
the int() operation already brings you to the float value with the smallest possible difference to ints - and in the case of 0 and 0. they are even identical.
so checking for is not zero should be sufficient, except maybe for the smallest possible 64 bit value (i am too dumb to test that within max)
Yes, of course. This is a "weakness point" of this solution (but you can just make the threshold smaller if you want to). However the "power point" is avoiding direct comparison, which may be problematic in case of floating point numbers. The most classic and reliable algorithm to compare floats for equality/inequality is by taking the absolute value of their difference and comparing it to a small enough (so called epsilon method).
I don't know if floatA == floatB in Max is epsilon-based. From my experience it is, but it is not explicitly declared, so to cut eventual problems it will be good to make a safe code.
Haha... this is really interesting conversation!
> i am a bit biased here because i use 32 bit max, and in 32 bit there is no real danger to use $f1 besides of int($f1)
64bit Max seems to be epsilon-proof too. I tried to force floating-point-comparison-error with no success (well... no error). Very interesting.
i believe the contradiction lies in the attempt to to "compare" float and int values already (i.e. in the OPs question), and not in the comparison between (int(float)) and (float).
(did you notice? you answered his question by writing "int" and "float" beside your result - but of course that is not what the patch is doing.)
and while you could lower the value to cover more use cases, it will require quite a lot of screenspace then, which the question after zero or nonzero does not.

more interesting, but not the case here, would be the question how to compare 3 against 3.* , without substracting them from each other, that is.
then we would have to find out if the incoming float is the closest possible float to 3 int. probably not a good idea to implement that using arithmetics, more a bitwise operations job.
Fixed threshold (epsilon) value is, even if I used it, also not a good practice, as this "error margin" should be calculated (or be accessible via some kind of interface) in accordance to formats of values we want to compare.
It's not precisely my field of interest, but, as far as I know, most of algorithms for int-float or float-float comparison are tailored for a specific applications and not to be a universal solutions.
I am happy to see that my "noob question" generates a so interesting conversation ;)
In my case all your solutions are working good. Thank you all to open my mind :)
In this case, I am looking for a way to know if a number is a multiple of 3, is it the more efficient way to divide it by 3 and after to route the results with your solutions ? I dont think of another ways. They are ?
then we would have to find out if the incoming float is the closest possible float to 3 int.
The closest possible float value to any integer is always an integer!
I would do this

you don't need that many decimal places , I guess
I prefer the solution which I posted on beginning on the topic, but technically-simplest-within-max option is probably something like that (however I don't like this solution for the reasons set out above):

"The closest possible float value to any integer is always an integer!"
well, if this was true, the problem would not exist.
987654321987654321 is stored as 110110110100110110100101111101111110111101000001001010110001, which represents 987654321987654321, but in float64 it is stored "with only 53 bits of precision" as 01000011 10101011 011010011011010010111110111111011110100000100101, which converts back to 9.87654321987654272E17.
if you attempt to compare these values, it will return false.
not to speak of the other issue, which is that you never know what a program/language actually does when converting between types, as far as i know there is not "wrong" and "right" for that.
9.87654321987654272E17 is an integer, so it doesn't disprove what I said: "The closest possible float value to any integer is always an integer!
>99,99% of all possible integers dont survive the conversion to float without errors, because in float the precision is lower.
that you get another integer value after doing int() is not so useful for comparing them.