- Home /
Problems comparing float with a Mathf.RoundToInt() version of itself
Hi.
I tried to calculate the screen's aspect ratio, so I created a static class and a function for that. I compared a float with a (int) and Mathf.RoundToInt() version of itself, but even though the numbers were the same, the loop crashes. To confirm that they were the same numbers, I put the exact same thing in an Update() and printed each version every frame, in an if statement, that checked if they were. In the console, I got very weird results. According to the results thrown in the console, the float itself was 4, and Mathf.RoundToInt() returned 4 as well, but checking if they were the same returned false, and the if statement which compared them continued running forever as well. If I put (int) before the variable name, it will return one less than it really is. If the float is 4, putting (int) before it will make it 3.
I found out that if I divide the width of the screen by height of the screen, then the first full (round) number I get when multiplying will be the first number, and the number used to multiply is the second one. (For example: 1920/1080=1,7777777777777, and 1,7777777777777*9=16. I had to multiply the number by 9 to get 16, so 16:9 is the correct aspect ratio.)
Here is what I did (C#):
public static Vector2 GetAspectRatio(int x,int y,bool debug){
float f=(float)x/(float)y;
int i=1;
// for(;f*i!=Mathf.RoundToInt(f*i);i++){
// if(debug)
// Debug.Log("Trying "+f*i+":"+i+"...");
// }
while(true){
i++;
int fi=Mathf.RoundToInt(f*i);
Debug.Log(fi);
if(debug)
Debug.Log("Trying "+f*i+":"+i+"...");
if(f*i==fi)
break;
}
if(debug)
Debug.Log("Current aspect ratio is "+f*i+":"+i);
return new Vector2(f*i,i);
}
And this is what I did to confirm the results (C#):
int i=1;
void Update(){
float f=(float)Screen.width/(float)Screen.height;
if((f*i)!=Mathf.RoundToInt(f*i)){
i++;
print("(float)f*i="+f*i+"(int)f*i="+Mathf.RoundToInt(f*i)+(f*i==Mathf.RoundToInt(f*i)));
}
}
And this is the output in the console of the script: (float)f*i=4(int)f*i=4False
I am confused by this, and I have no idea what to do. Any ideas or solutions would be very much appreciated.
Thanks in advance!
bump
Any suggestions? Is there maybe another way to calculate aspect ratio?
Why do you need to get the aspect ratio?
If you are looking for positioning with aspect ratios, this might work ins$$anonymous$$d:
If you design for a specific aspect ratio (e.g., 16:9), you should be able to just multiply whatever position you originally had by its inverse (9/16) to undo the aspect and then multiply it by the new aspect ratio (Screen.width/Screen.height) to get its proportional position.
Answer by Owen-Reynolds · Nov 30, 2013 at 04:51 PM
Common programming with floats issue. You write that 1.77777777*9 is 16, but clearly it isn't -- it's 15.999999992. Printing lies to you. It rounds to the nearest ~millionths place (like how Unity vectors round to the nearest tenth.)
You get the same error for i=1.0f/7.0f; i=i*7;
. There are lots of different threads about it scattered in UA (names like "floats don't work") or general programming sites.
In your case, maybe just compare x/y to all known aspect ratios and choose the closest?
Thanks! Had to round it to two decimals using System.$$anonymous$$ath.Round()
, works perfect now!
One "official" method is to check the numbers are within 0.01-ish of each other (`if($$anonymous$$athf.Abs(n1-n2)<0.01f)`). I think your method amounts to the same thing, just going the other way.