- Home /
Floating point correction
I'm making a rotation script for a slot machine and it works well with few bugs: a Floating point error that causes it to avoid landing squarely on a number (landing on 59.99997 instead of 60.0).
I need a way to remedy this and I've come up with two solutions:
1.) Compare two numbers to see if they equal each other, plus or minus 0.50. The current script compares the transform.rotation.
2.) Use Quaternion Slerp on a specific EulerAngle(EulerAngle.x alone to be exact) I heard that rotation done by Quaternion Slerp could stop floating point from appearing.
I know how to compare two numbers but not with an additional range of 0.50.
Can someone show me how to do either one or present some other solution?
Answer by rejj · May 01, 2011 at 07:01 AM
If you know the number you need to compare against (in your example's case, 60) you can use Mathf.Approximately()
eg,
if (Mathf.Approximately(transform.rotation.x, 60f)) {
// close enough, treat it like it was 60
}
edit
A function such as the following should help you with point 1 in your question:
bool AlmostEqual(float a, float b, float epsilon) {
return Mathf.Abs(a - b) < epsilon;
}
In your example where you wanted to check if two numbers are within 0.5, you would pass in 0.5 as the epsilon value.
Since what it stops on is random, I need to compare it against the final rotation ins$$anonymous$$d of a predeter$$anonymous$$ed number
What is your purpose? Is the thing stopping by itself, and you want to know where it stopped, or is it rotating and you want to check if its time to stop it?
It stops itself after a few seconds but once it does, it moves to a position in order to land on symbol.
Answer by Meltdown · May 03, 2011 at 07:09 PM
The following code works for me. Simply convert your float to an int.
int xAngleInt = 0; float xAngle = 0;
void Update() { xAngle = 59.9994F; // Set your random angle here xAngleInt = Convert.ToInt32(xAngle); }
void OnGUI() { GUI.Label(new Rect(10, 10, 100, 100), xAngleInt.ToString()); }
In this case the value of '60' will always be shown. So no matter what xAngle is set to in your Update() method, your true integer value will only be shown.
if you don't need the decimal value this is the best way to go I$$anonymous$$HO, if you do, just multiply by 10, 100, etc $$anonymous$$athf.Convert or $$anonymous$$atf.RoundToInt then divide back by the value used
Answer by Joshua · May 01, 2011 at 05:17 AM
Don't use transform.eulerAngle, it won't work if the rotation is more then 360 degrees and if you're making a slot machine I imagine you'll want it to spin more then that. Use transform.Rotate instead. But in this case I would just use
Mathf.RoundToInt(59.99997) //returns 60
It will return the nearest int. If it's exactly in between two ints (like 1.5 for instance) it will return the even one of the two, so.. two in this case ^.^
It has to be Euler Angles with how the script is set up and even when I converted the script to work with rotation in place of Eulers, It didn't solve the problem
Answer by almo · May 03, 2011 at 07:18 PM
You could keep the angle from last frame, and compare the two. If that difference is small (you pick how small) you decide that it's done moving, then set it equal to the nearest integer and set your display accordingly.
Your answer
Follow this Question
Related Questions
Float check not returning the right value. 1 Answer
How can I create a working and semi-realistic lift force? 0 Answers
Unknown error 1 Answer
floating point model using by unity 0 Answers