Search Unity

1/5 = 0 and 1f / 5f = 0.2 (Even when both stored in a float)

Discussion in 'Scripting' started by Aeroxima, Aug 17, 2018.

  1. Aeroxima

    Aeroxima

    Joined:
    Jul 19, 2016
    Posts:
    15
    I figured out my problem now, but I thought I'd post anyways because I spent too much time on it.

    Code (CSharp):
    1.     float f;
    2.  
    3.     f = 1 / 60;
    4.     Debug.Log(f);    //Gives: 0
    5.  
    6.     f = 1f / 60f;
    7.     Debug.Log(f);    //Gives: 0.01666667
    It's like it's being cast to int, but everything is still fine even with the different types.

    This explains some things:
    https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/types/casting-and-type-conversions

    But it's still weird. It says:

    Implicit conversions: No special syntax is required because the conversion is type safe and no data will be lost.

    Explicit conversions (casts): Explicit conversions require a cast operator. Casting is required when information might be lost in the conversion, or [...]​

    But what I was doing was causing me to lose data, and there was no warning or error about it. I guess the lesson is to just be careful and mindful about what types your constants are.

    (To be clear, I see now they were int to begin with, and casting to float to save it was considered lossless. The loss was when dividing int / int. Each part on its own makes sense, but all together the result is silently lost data.)
     
  2. MD_Reptile

    MD_Reptile

    Joined:
    Jan 19, 2012
    Posts:
    2,664
    Yeah, its just a C# thing, and well, probably most languages really...

    If you write 1.0f instead of 1 it'll always work. It'll also always do float division if you hand it float variables (whether they equal a whole number or not), so you just have to keep that in mind when doing complex math on floats or integers.

    To C# when you say "1" your saying "the integer 1", and when you say "1.0f" or "1f" your saying to the compiler "the floating point value of 1" - otherwise it has to make assumptions about what you mean.
     
  3. Joe-Censored

    Joe-Censored

    Joined:
    Mar 26, 2013
    Posts:
    11,847
    This is why it is important to use a numeric literal suffix in your code. If you don't then numbers with a decimal point will default to "double" and without will default to "int". This can result in unintended implicit conversions that at best make your code run ever so slightly slower, or at worst you get errors saying you need an explicit conversion or get unintended lost data or unexpected results.

    1f: float
    1d: double
    1u: uint
    1l: long
    1ul: ulong
    1m: decimal
     
    lordofduct and Aeroxima like this.