Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by LastFarmer · May 03, 2020 at 01:36 PM · floatintdivision

int conversion gives bad results !

Hello !

I discovered an abominable error on a simple division. The problem is quite simple: 5/0.2 = 25, right ?

Well, by using float we have no problem 5f / 0.2f ------> 25. Great

But try to make... (int) (5f / 0.2f)------- > and you'll get 24 !! The system loses a number ! And with it, I'm lost as well.

Anyone knows how to fix this unspeakable bug ? Thank you.

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

3 Replies

· Add your reply
  • Sort: 
avatar image
0
Best Answer

Answer by Eh3an · May 03, 2020 at 02:00 PM

It's very important that the cast will occur before the division, so you can store division operation into a variable and then cast that variable to int.

 float r = 5f / 0.2f;
 (int)(r)

Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image LastFarmer · May 03, 2020 at 02:07 PM 0
Share

Thank you Eh3an ! Your solution solved the issue and cleared the mystery !

avatar image
3

Answer by Bunny83 · May 03, 2020 at 05:51 PM

Even others have answered the question already I'd like to mention a few things.


First of all if you are surprised by this result I highly recommend to watch this numberphile video. Once you understand that floating point numbers will never really be accurate except for some special numbers you should always keep that in mind when you want to convert it into an integer.


Note that casting a floating point value to an integer will actually not round down but rounds towards 0. So a value of "1.5" is casted to "1" but a value of "-1.5" is casted to "-1" (so rounded up). Unity provides several methods to perform rounding. First there's Mathf.Floor and Mathf.Ceil. Those are the equivalent functions from actual math. Floor will always round down while Ceil will always round up. Though we also have the Mathf.Round method which rounds down if the value is below 0.5 and rounds up if it's above. 0.5 is a special case I won't go into detail here.


In addition to those 3 methods Unity also provides another set of those methods which directly perform an int conversion for you. Specifically Mathf.RoundToInt, Mathf.FloorToInt and Mathf.CeilToInt. If you perform a floating point calculation where the result would be very close to a whole number, you should always use RoundToInt to be on the safe side. Because if the value of 24.999999 or 25.000001 both would come out at 25

 int val = Mathf.RountToInt(5f / 0.2f);


Unity, C# and almost all other programming languages just use the hardware implementation of floating point numbers as it's defined in the IEEE 754 standard. It specifically defines 2 types: 32 bit (single precision floating point numbers) and 64 bit (double precision floating point numbers). In .NET they are called System.Single and System.Double. However C# has two alias names for those types we all know: float (==System.Single) and double (System.Double).


If you want to quickly explore how 32 bit floating point numbers work under the hood, have a look at this online converter. If you think you want / need to convert or examine those numbers more in detail you might want to have a look at my little editor window which provides a similar functionality but also for double and integer values.

Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image LastFarmer · May 03, 2020 at 06:02 PM 0
Share

Thank you Bunny83 ! The $$anonymous$$athf.RoundToInt will be a new friend of $$anonymous$$e ! :)

avatar image
1

Answer by GregoryFenn · May 03, 2020 at 02:44 PM

It's not a bug. When you are using floats, you are by definition only intested in lengths/weights/scalers up to an approximate value, where being over or under by 2^(-22) is acceptable. In your case, you are complaining that 24.99999 is being cast to int 24. That's not a bug with the system or the language, it's a bug with your code.

If you need to round to the NEAREST int, then use Mathf.RoundToInt, or something like that.

Strictly speaking, you shouldn't even assume that the statement

 int x = (int)(25f); // could assign 24 or 25 to x

will define x as 25. Casting to int will always round towards zero, and it's possible that the closest float that the compiler will find to 25f is in fact 24.99999 (remember it works in binary, and my examples have been in decimal).

I suspect x would be 25 in this case, because for small integers, you can exactly represent them with floats, but for larger integers, that wouldn't be true: e.g. int x = (int)(9876543f); might return 9876540, for example.

If you have a float which is meant to be an int, such as 25f, or 5/(0.2f), then one approach would be to define

 int x = (int)(25f + 0.0001f);

to stop the potential rounding error.

I don't know how C# handles floats, but if you look at how 32 bit floats ("single-precision") work in C, you'll see what I'm talking about: https://en.wikipedia.org/wiki/Single-precision_floating-point_format#IEEE_754_single-precision_binary_floating-point_format:_binary32

Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image LastFarmer · May 03, 2020 at 03:37 PM 0
Share

Thank you GregoryFenn. $$anonymous$$uch clearer now !

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

128 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

float = int / int float value always 0 1 Answer

Javascript int to float 1 Answer

Having a GUI text as a int 3 Answers

"Talent Tree" global yes/false var and int? 3 Answers

Float to Int 4 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges