Hello!
I ran into a really confusing problem today.
I have int number with lots of “9” in it, for example 690999994, and I want to get 3 last numbers from it.
Its sounds simple: float f = 690999994%1000f. But I’m getting f = 0f.
And if I try to just devide it by 1000f, I’m getting 691000 instead of 690999.994f.
Am I doing something wrong?
learn how floating point numerical representation works in modern computing. it has nothing to do with Unity, Unity just complies with the industry standards. decimal points are a real pain in the ass, and so the most common standard has to live with some numerical inaccuracies that may crop up in specific corner cases, like yours, or when used at the extreme ranges.
integers on the other hand, are incredibly accurate, but usually limited in range or sign, by design.
so if you’re having an integer, converting it to a floating point by division is very similar to taking a picture of your screen with a cell phone, then telefaxing a scan of a printed copy.
if you want to reliably sample some digits from your integer, there are other tools at your disposal.
for example you can use an integer division, or you can use a bitwise operation.
heck, you can even convert it to a string and manipulate it that way.
in your case in particular, you want to use a so-called division remainder operator %
which will return whatever remains after a specific integer division.
AND YOU DID THIS, but for some reason you’re not dividing by integer, so you’re getting a regular division.
so this is a really long explanation of why exactly you should get rid of that ‘f’ after 1000
int remainder = 690999994 % 1000;
Debug.Log(remainder); // prints 994
Don’t ever forget that nearly all arithmetic C# operators work with a range of types, and in many IDEs you can hover over an operator to see exactly what types it will assume.
Many obviously work with both integers and floating point types, normally +
-
*
and /
, but some will also employ a completely different computation algorithm (like /
and %
) depending on the type. Some even work with strings like +
. Some can’t work with numeric types, like !
, and some can’t work with floating point types, like &
or ^
.
If you combine two different numeric types inside a binary operation (that means it has two operands), C# compiler will typically upcast one of them (upcasting is a process of casting one operand to a type that is guaranteed not to truncate existing data).
690999994 % 1000f
does not produce a compile error, because %
assumes a floating point operation because you’ve explicitly stated you want a floating point on the right hand side. It probably did yell at you for the result, and this is why you declared that variable as float
.
But why would you ever want a float
when you’re extracting an int
from an int
? Be mindful of your types.
Thank you so much for sharing your wisdom.
That’s just confirms a basic truth - without proper education and well learned basics of computer science even 5+ years of game development experience is not enough.
One more thing: That f
is called a “literal suffix” and is used to hint a literal type. For example d
would hint a double
. There are a dozen of these in total. Don’t just throw them around, use them with care. You can find more about it here.
Thanks a lot!
Indeed, I made a very stupid mistake. From now on, I will double check my types.
Dude I’ve been making games for 42 years now.
I’m still surprised by brand-new things that I never knew about.
That’s what’s so awesome about learning!
You can do it FOREVER!!!
Even better, as you get older you start forgetting stuff, then you can learn it ALL OVER A SECOND TIME!
I love it.