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!

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?