- Home /
Raycast is not returning exact number / Mesh is not exact dimensions
I am trying to select faces of a cube with raycasting. I converted the RaycastHit.point to a local vector relative the transform of the collider hit. The box collider I created is exactly 0.2 units. Therefore when I got my RaycastHit.point and I converted it to local coordinates, I tried to use the Vector3 to select the face. So for example the vector (0,0.1,0) would be the top of the cube. The problem is that when I log the vector axes, the value that should be 0.1 (The face) is actually logged as 0.0999999. I can't even use this number to choose the faces because it is infinitely repeating and I have no idea how to solve this problem. Any advice would be greatly appreciated.
Answer by Kishotta · Jul 13, 2017 at 09:44 PM
So this is actually due to how floating point numbers are handled in computers (not Unity specifically). Floating point numbers are expressed as powers of 2.
0.125 is a power of 2 (2^-3) but 0.1 is not and can therefor not be perfectly represented with a float (or double for that matter). This is why you should never check equality between floating point numbers. They just can't be represented in the number of decimal places you have.
That being said, you can use Mathf.Approximately to check if floating point numbers are "close enough" to one another.
I was going to try that but I wasn't sure if that was the right way to do it. Anyway, thank you very much for the information on how floating point numbers are handled. I had no idea they worked like that and I will surely remember that from now on.
It may be way more in-depth than you care to get, but this converter shows exactly what happens at the per-bit level.
The $$anonymous$$antissa is a way of "scaling" the power of 2. You'll notice when you enter values like 2, 4, 16, etc that the $$anonymous$$antissa is 1. But when putting in something like 5, the $$anonymous$$antissa scales up a smaller power of 2 (2^2).
Okay, so your solution worked some of the time but it didn't always return true. I ended up just specifying a range that deter$$anonymous$$es the selected face. Here is one snippet out of the code:
if (hitPosition.z > 0.099f && hitPosition.z < 0.11f)
{
placePosition = Vector3.forward * 0.2f;
selectedFace = "front";
}
This ended up working every time. I really appreciate all of the help and information from everyone though :)
Answer by Cornelis-de-Jager · Jul 13, 2017 at 09:54 PM
Well it seems the number is close enough each time so just round it:
double num = Math.Round (yourNum, 1); // Rounds to first decimal