Welcome, Guest. Please login or register.
Did you miss your activation email?

Login with username, password and session length

 
Advanced search

1057130 Posts in 42938 Topics- by 34885 Members - Latest Member: nmonte

October 25, 2014, 01:27:22 AM
TIGSource ForumsDeveloperTechnical (Moderators: Glaiel-Gamer, ThemsAllTook)Floats & integers in Unity?
Pages: [1]
Print
Author Topic: Floats & integers in Unity?  (Read 1110 times)
iam0a1
Level 0
*



View Profile
« on: May 04, 2013, 10:36:05 AM »

I'm going through the Unity 3.x Game Development Essentials book, which I am finding very helpful, but there is a code listed in here that I find confusing.
This is written in Unityscript, but in this book the C# example also lists these numbers as floats as well.
EX. 1
Code:
var power : float = 1500;
Should this actually be :
Code:
var power : int = 1500;
EX. 2
Code:
var moveSpeed : float = 5;
why not :
Code:
var moveSpeed : int = 5;
Why does the book consider this a float? Can you just consider any value
a float since there is a understood decimal value of .0 at the end of
every number?
 If so, when does int actually come into use?
Logged
milo_dercius
Level 0
**



View Profile Email
« Reply #1 on: May 04, 2013, 10:43:05 AM »

Just because they are not assigning a value with a decimal does not mean that they should be using an int. Making them floats or doubles allows the math that gets done with them to have a decimal answer later on. Int is more precise and is used when you are not going to have decimals in your calculations.
Logged
BleakProspects
Level 4
****



View Profile WWW Email
« Reply #2 on: May 04, 2013, 10:50:56 AM »

Integers are a subset of *real* numbers. Floating point (float, double, etc.) is a way of representing a large amount real numbers using a fixed amount of memory. Integers (int, long, short, etc.) are a totally different way of representing *integer* numbers using a fixed amount of memory. In this way, floating point numbers are *totally incompatible* with integer representations of number.

In most programming languages, "literals" (the actual numbers you put down, like '5') can be interpreted in a variety of different ways depending on context. The number 5 might be interpreted as an integer, a character, a real number, or even an enum depending on the context in which it is used. So saying

Code:
float v  = 5;

Is really telling the compiler "Make a block of memory 32 bits wide and fill it with the floating point representation of the number 5". It is exactly the same as writing

Code:
float v = 5.0;

or

Code:
float v = 5.00000000;

or

Code:
float v = 5e1;

Wheras if you say this:

Code:
int v = 5;

You are saying to the compiler "give me a block of memory 32 bits wide initialized with the integer representation of 5". But the floating point representation and the integer representation in memory for the number 5 are completely incompatible. If you tried this instead:

Code:

// Error!
int v = 5.0;

The compiler has no idea what to do, because there is no integer representation of "5.0". The addition of the ".0" at the end turns the integer literal "5" explicitly into a real number literal.  For this reason, in code, an integer equal to 5 is not the same as a floating point number equal to 5.
« Last Edit: May 04, 2013, 10:56:30 AM by BleakProspects » Logged

iam0a1
Level 0
*



View Profile
« Reply #3 on: May 04, 2013, 11:01:50 AM »

Thanks guys, really helpful. I understand it now.
Logged
Sar
Level 3
***


Likes Violins


View Profile WWW
« Reply #4 on: May 04, 2013, 12:43:06 PM »

Code:

// Error!
int v = 5.0;

However, it's probably worth noting that you can still (in most languages, I'm pretty sure it's the case for UnityScript and it's definitely the case for C#) do an equality check between ints and floats:

Code:
int v = 5;
if (v == 5.0)
{
    // This code will execute
    ...
}



It's also worth noting that floating point numbers are the work of the devil, because they actually only store an approximation of the number you give them. If you ever have any weird accuracy problems in your game that you can't track down, they probably came from your use of floating point numbers. But we still use them because they're faster than fixed-point arithmetic. ;_;
Logged

Currently working on: Chronicle of Mars
Previous Projects: [Käfer|Tristan and Iseult(TIGS)]
ham and brie
Level 3
***



View Profile Email
« Reply #5 on: May 04, 2013, 01:05:34 PM »

It's also worth noting that floating point numbers are the work of the devil, because they actually only store an approximation of the number you give them. If you ever have any weird accuracy problems in your game that you can't track down, they probably came from your use of floating point numbers. But we still use them because they're faster than fixed-point arithmetic. ;_;
Fixed point numbers are also approximations.

The reason we use floating point is that difference between one number and the next is relative to how large the number is. With fixed point you can get greater (but still not perfect) precision for the same number of bits, but only if the number is within a particular range, so you have to write your code according to what range the values will be in to have that advantage.
Logged
xgalaxy
Level 0
***



View Profile
« Reply #6 on: May 04, 2013, 10:40:35 PM »

Not sure exactly on C# but in C/C++ doing:
Code:
float foo = 5;
is technically creating an int and converting it to a float. Eg, the compiler is actually doing this:
Code:
float foo = (float)5;

To avoid that, create foo like so:
Code:
float foo = 5.f;

If you simply did the following:
Code:
float foo = 5.0;
Then the compiler is technically creating a double and converting it to a float.

The reason this becomes important is because if your doing math, instead of just simple assignment, the compiler will convert the values to the higher order type and this will be slower than if you used the correct types. For example if you were to do the following:
Code:
float foo = 5.f;
float bar = foo * 2.0 + 1;

Then foo and 1 get converted to a double, then the math calculations are made, and then the result is converted back to a float. So not only do you have unwanted type conversions, you also have slower double precision math calculations and potential loss of precision. And if that wasn't enough you may also have a higher likelihood of bugs due to unwanted conversion from signed to unsigned values.

So the take away from this is that even though the compiler will, in most cases, implicitly do the type conversion automatically, you should err on the side of being explicit because often times the compiler is going to do something you didn't intend.
Logged
Sar
Level 3
***


Likes Violins


View Profile WWW
« Reply #7 on: May 05, 2013, 12:48:10 AM »

Fixed point numbers are also approximations.

Yes and no. Fixed-point numbers are absolutely precise if the number you put into them is within the range of precision that type can hold, which is a known constant which you can work to; floating-point numbers are precise almost at random - generally because of the results of calculations you do; two calculations at the same magnitude which produce the same number sometimes come up with different results using floats, for example*.

With fixed-point arithmetic, you know the exact limitations of the numbers in advance and if you know that your number space fits entirely within those limitations, you can be happy that fixed-point maths is going to absolutely be good enough for you; with floats, you can't trust the damn things further than you can throw them. And they're incorporeal.

* Example, from C#, responses indented by me.
Code:
12/0.4
  30.0
1.2/0.4
  2.9999999999999996
1.2*2.5
  3.0
I know why that's happening, and I expect you know why that's happening, but I also expect that to your average newbie who has to ask questions like the one starting this thread, that's going to read as "the computer is broken".

Unfortunately C# doesn't have a standard fixed-point type to use instead. Which is enough of a grounding as any that floats are good enough for most purposes. The built-in Decimal type is widely considered a fixed-point type but in fact is just another floating-point type!
Logged

Currently working on: Chronicle of Mars
Previous Projects: [Käfer|Tristan and Iseult(TIGS)]
ham and brie
Level 3
***



View Profile Email
« Reply #8 on: May 05, 2013, 01:34:37 AM »

* Example, from C#, responses indented by me.
Code:
12/0.4
  30.0
1.2/0.4
  2.9999999999999996
1.2*2.5
  3.0
I know why that's happening, and I expect you know why that's happening, but I also expect that to your average newbie who has to ask questions like the one starting this thread, that's going to read as "the computer is broken".

Have you actually tried doing those calculations with a binary fixed point type?
Logged
Sar
Level 3
***


Likes Violins


View Profile WWW
« Reply #9 on: May 05, 2013, 02:47:55 AM »

Have you actually tried doing those calculations with a binary fixed point type?

Off the top of my head, I think the only fixed-point type I have on my PC right now is in SQL, so excuse the verbose example:

Code:
declare @x numeric(38, 37)
declare @y numeric(38, 37)
declare @result numeric(38, 37)

select @x = 1.2
select @y = 0.4
select @result = @x / @y

select @result
Code:

---------------------------------------
3.0000000000000000000000000000000000000






There are several languages which have 'extra precision numeric' types which are just fancy floats, like C#'s Decimal type - are you sure you're not thinking of those?
Logged

Currently working on: Chronicle of Mars
Previous Projects: [Käfer|Tristan and Iseult(TIGS)]
ham and brie
Level 3
***



View Profile Email
« Reply #10 on: May 05, 2013, 03:51:09 AM »

That's a 17 byte (!) decimal type. I said binary fixed point type.

Decimals types make sacrifices to favor decimal numbers. Decimals are special to humans (e.g., you chose 12/10 and 4/10), so they're appropriate for some applications, but not for general calculations in games. You can have not only slower calculations and more memory used, but also larger errors in the results.

Even without a binary fixed point type, you could still try out the equivalent integer maths.
Logged
Sar
Level 3
***


Likes Violins


View Profile WWW
« Reply #11 on: May 05, 2013, 02:40:48 PM »

... appropriate for some applications, but not for general calculations in games. You can have not only slower calculations and more memory used, but also larger errors in the results.

Wasn't that my point in the first place? Leaving aside that "larger errors in the results" is really only the case if you go outside of the bounds of the type, which frankly is a problem with every type in one form or another! You have to use floats in games for a lot of things, because fixed-point arithmetic isn't fast enough... but it's still worth being aware of the limitations with floats so you're not too surprised when - say - (1.2/0.4 >= 3) evaluates to false. Which it does, and by proper mathematics it shouldn't. A lot of people think "floating point number" means "real number" and because of that they can't work out what's wrong with their code.

(Whether you like it or not your game code will use decimal numbers, unless you do all your operations with bitwise operators and shifts.)

Yes, a lot of these problems are due to the fact that there is a set of rational numbers that can't be exactly represented in binary and there is a different set of rational numbers that can't be exactly represented in decimal. But the practical point is that you have to be more careful with floating point numbers than pretty much every other type you encounter in day-to-day games programming.

(Integer maths [scaled up by a fixed magnitude] naturally works and doesn't work, depending on how your integer divisions are calculated.)
Logged

Currently working on: Chronicle of Mars
Previous Projects: [Käfer|Tristan and Iseult(TIGS)]
ham and brie
Level 3
***



View Profile Email
« Reply #12 on: May 06, 2013, 12:03:31 AM »

Leaving aside that "larger errors in the results" is really only the case if you go outside of the bounds of the type, which frankly is a problem with every type in one form or another!
Not sure what you're trying to say here. It's the case if a calculation produces an approximate result. Which is what you're complaining about with floats...

Quote
You have to use floats in games for a lot of things, because fixed-point arithmetic isn't fast enough...
Speed is not why we use floats over fixed point.

Quote
but it's still worth being aware of the limitations with floats so you're not too surprised when - say - (1.2/0.4 >= 3) evaluates to false. Which it does, and by proper mathematics it shouldn't. A lot of people think "floating point number" means "real number" and because of that they can't work out what's wrong with their code.
And you seem to be implying fixed point is different in this respect, but it's not.

Quote
(Whether you like it or not your game code will use decimal numbers, unless you do all your operations with bitwise operators and shifts.)
I mean decimal in the sense of base-10. You might use base-10 for human readable representations of numbers (such as float literals in source code), but all operations are performed in base-2.

Quote
Yes, a lot of these problems are due to the fact that there is a set of rational numbers that can't be exactly represented in binary and there is a different set of rational numbers that can't be exactly represented in decimal.
This is relevant to why your example worked better with a decimal type (which says little about fixed point vs floating), but it's not particularly important in general calculations.

Quote
But the practical point is that you have to be more careful with floating point numbers than pretty much every other type you encounter in day-to-day games programming.
And fixed point involves at least as much care.

Quote
(Integer maths [scaled up by a fixed magnitude] naturally works and doesn't work, depending on how your integer divisions are calculated.)
Huh?
Logged
Sar
Level 3
***


Likes Violins


View Profile WWW
« Reply #13 on: May 06, 2013, 12:58:31 AM »

This is relevant to why your example worked better with a decimal type (which says little about fixed point vs floating), but it's not particularly important in general calculations.

It's relevant because literally all of the fixed-point types - both built-ins and extensions people have written because they want the functionality - that I've come across recently in modern programming languages have been fixed-decimal-point rather than fixed-binary-point types. Which work without conversion problems but are much slower than floating point arithmetic. Largely because fixed-binary-point types are... kind of useless compared to floats?

But my main point - which you seem to be ignoring in favour of a desperate attempt to prove that something I didn't say is wrong - was that you have to be aware that floating point numbers are not the same as real numbers. *Sigh*. I really don't see much point continuing this discussion.
Logged

Currently working on: Chronicle of Mars
Previous Projects: [Käfer|Tristan and Iseult(TIGS)]
ham and brie
Level 3
***



View Profile Email
« Reply #14 on: May 06, 2013, 02:11:21 AM »

It's relevant because literally all of the fixed-point types - both built-ins and extensions people have written because they want the functionality - that I've come across recently in modern programming languages have been fixed-decimal-point rather than fixed-binary-point types. Which work without conversion problems but are much slower than floating point arithmetic.
Even if that's been your experience so far, fixed point shouldn't be confused with decimal types.

Try googling fixed point library and see what you find.

Quote
Largely because fixed-binary-point types are... kind of useless compared to floats?
No, they definitely have uses.

Quote
But my main point - which you seem to be ignoring in favour of a desperate attempt to prove that something I didn't say is wrong - was that you have to be aware that floating point numbers are not the same as real numbers.
I'm not ignoring that. That's fine. I'm not disagreeing with that.

I'm not replying because I want to prove a point. I was genuinely trying to be helpful in pointing out that fixed point is also approximate, because what you wrote implied it avoided a problem which it doesn't actually deal with.
Logged
ThemsAllTook
Moderator
Level 10
******


Alex Diener


View Profile WWW
« Reply #15 on: May 06, 2013, 11:41:02 AM »

With fixed-point arithmetic, you know the exact limitations of the numbers in advance and if you know that your number space fits entirely within those limitations, you can be happy that fixed-point maths is going to absolutely be good enough for you; with floats, you can't trust the damn things further than you can throw them. And they're incorporeal.

(I'm coming into this discussion a bit late, pardon the several-posts-back quote)

I used to think the same thing about floats, but this page really helped me understand their anatomy and demystify them: http://en.wikipedia.org/wiki/IEEE_754-1985

After studying that a bit and running a few tests, floats make a lot more sense, and errors in them are fairly predictable. However, error can vary slightly across CPU architectures - although the same calculation will always give the same result on one CPU, it might have one bit of difference on another, which can be enough to throw off an entire simulation in some cases. Binary fixed point numbers (never heard of a decimal fixed point implementation before, that sounds crazy!) solve that problem by using integer arithmetic which is 100% consistent everywhere, at the cost of precision, performance, and easy access to math functions like sin(), sqrt(), etc.
Logged
Sar
Level 3
***


Likes Violins


View Profile WWW
« Reply #16 on: May 06, 2013, 12:01:24 PM »

errors in them are fairly predictable

In my experience, the problems most people will encounter with floats are more that they don't expect the errors in the first place.
Logged

Currently working on: Chronicle of Mars
Previous Projects: [Käfer|Tristan and Iseult(TIGS)]
Pages: [1]
Print
Jump to:  

Theme orange-lt created by panic