Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Question floats vs ints in terms of precision

Discussion in 'Scripting' started by miccalisto, Mar 6, 2023.

  1. miccalisto

    miccalisto

    Joined:
    Feb 20, 2018
    Posts:
    40
    Is it good to use floats for numbers that will be changed very often? For example in my game there's the number of food a player has. Its changing every few seconds based on various incomes and outcomes.

    Can some precision issues arise later in the game after the number would have been changed many times?

    There are a lot of other important stats where the precision is really important so I'm a little worried.
     
  2. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    5,893
    Well the first question to ask is, do you need decimal places or not? When I see "number of food a player has", I imagine there would only be whole numbers, thus, use integers.
     
  3. miccalisto

    miccalisto

    Joined:
    Feb 20, 2018
    Posts:
    40
    Yes, but in that case I would have to use quite big numbers, with decimals I can have a production of like 4.55 and max cap 2000, with ints I would need 455 and max cap 200000 for the same ratio.
    Also there are stats like percentages so if I should hold it in integers like 951 and each time divide it by 10 or if I could use floats like 95.1 with the same precision,.
     
  4. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    5,893
    Well floating point precision (or better put, their imprecision), is well documented, so consider that some homework reading material. If you absolutely require higher levels of precision, there is
    double
    (double the precision of float) and
    decimal
    (complete precision, only really designed for money oriented programs). Though
    decimal
    is generally too slow for games, while
    double
    should be good if you absolutely require that level of precision.

    Otherwise, yes, you can work with ints and just divide by 100 or whatever as needed. It's a pretty common practice in game dev in certain situations.
     
    Last edited: Mar 6, 2023
  5. dogmachris

    dogmachris

    Joined:
    Sep 15, 2014
    Posts:
    1,373
    Quick and dirty answer
    float precision is more than enough for your needs. Unless you're doing rocket science or something equally complex, you'll be just fine.

    Long answer
    Well here's a little crash course on the peculiarities of some primitive data types - just in case you care to know:

    A "bit" is just a fancy way of saying a binary digit, which can only be 0 or 1. An int can hold up to 32 bits worth of integer data, which is just whole numbers. Here's how it works:

    Say we have 2 bits at our disposal, to store whole numbers, that would mean

    00 = 0
    01 = 1
    10 = 2
    11 = 3

    Now say we have 3 bits:

    000 = 0
    001 = 1
    010 = 2
    011 = 3
    100 = 4
    101 = 5
    110 = 6
    111 = 7

    So as you can see the range of whole numbers, an int can store is 2^(amount of bits). One bit is reserved for the sign (+ or -) and so you can store anything between -(2^31) and 2^31 in an int.

    Now a float can also hold 32 bits of data, but its' representation is different. As you may have seen, when you feed a float with a very large or very small number, the notation will change to something like 1.5124687e12 (e being short for x10^).

    Now look closely at that notation, because its' bits are staring right back at you. The bits are used differently than they are in an int. They are distributed across the notation like this:

    1 bit for the sign
    8 bits for the exponent (biased notation, watch out!!)
    23 bits for the fractional remainder (mantissa - only gets the leftovers)

    No bits are reserved specifically for the integer part of the float, it's instead determined implicitly by the position of the decimal point.

    The 23 bits for the mantissa mean that it can have a maximum of 7 digits of precision, everything beyond is cut off and that's the max precision you get. Here's what it means when we talk about precision:

    Say we have the number

    1,451,624,648

    An int would store it as it is in standard notation, but a float doesn't have enough digits to do that, so it would store it as

    1.4516246e9

    Now if you go back from this scientific notation to the standard notation, you get

    1,451,624,600 <== which is 48 less than what you wanted to store.

    The same precision loss happens for very small numbers. However the representation of values in a float also means that it can store spectacularly large and sub-atomically small numbers compared to an int, it just loses some presicion along the way.

    So there you have it. Don't get too caught up in the technical details - float precision is more than enough for your needs, unless you're planning on launching a spaceship or something.
     
    Last edited: Mar 7, 2023
  6. miccalisto

    miccalisto

    Joined:
    Feb 20, 2018
    Posts:
    40
    Ok, I will use floats then, wasn't quite sure, but I appretiate your explanation.
     
  7. SeerSucker69

    SeerSucker69

    Joined:
    Mar 6, 2021
    Posts:
    65
    Thanks for that awesome write up! Appreciate it.
     
  8. Owen-Reynolds

    Owen-Reynolds

    Joined:
    Feb 15, 2012
    Posts:
    1,921
    The difference between float and int in your case would be the tiny imprecisions. Most decimals can't be represented exactly in binary, which means production of 4.55 is very, very, very close, but not exactly 4.55. After 100 seconds you should have 455 units but it might be only 4.54999 or 4.55001. After ten minutes you might have 1 more or less unit than you should. In some cases this might be noticeable -- like the player has production set-up perfectly but very slowly unused iron piles up.

    Taking out the decimals, converting 4.55 to 455, removes that tiny problem. You can do that using floats, but you still have to be careful with division, floats are a little slower, and (as dogmachis write) they can't store as "long" numbers like 12345643 which ints can, so it's common to use ints for decimal-free values.