So I don't really get the conversion from a float to a double e.g:
float wow = 1.123562641346;
float wow = 1.123562641346f;
The first one is a double that gets saved in a variable that has memory reserved for a float and it can't implicitely convert to a float so it gives an error.
The second one has on the right side a float being saved inside a float variable. What I don't get is that the second one gives exactly the same result as this:
float wow = (float) 1.123562641346;
I mean the second one is it just exactly the same as (float), does the "f" just stand for explicitely convert to a float?
If it doesn't mean "explicitely" convert to float, then I don't know why it doesn't give an error since there isn't an implicit conversion for it.
I really can't find any resources that seem to explain this in any way, the only answers I can find is that the "f" just means that it is a float data type, but that still doesn't explain why I can give it something with 13 decimals and it converts it to the 7 decimals expected, while the first solution doesn't work and it doesn't automatically convert it.
CodePudding user response:
Implicitly converting a double to a float is potentially a data-losing operation, so the compiler makes it an error.
Explicitly converting it means that the programmer has taken control, so it does not provoke an error.
Note that in your example, the double
value does indeed lose data when it's converted to float
as the following demonstrates:
double d = 1.123562641346;
Console.WriteLine(d.ToString("f16")); // 1.1235626413460000
float f1 = (float)1.123562641346;
Console.WriteLine(f1.ToString("f16")); // 1.1235626935958862
float f2 = 1.123562641346f;
Console.WriteLine(f2.ToString("f16")); // 1.1235626935958862
The compiler is trying to prevent the programmer from writing code that causes accidental data loss.
Note that it does NOT warn that float f2 = 1.123562641346f;
is trying to initialise f2
with a value that it cannot actually represent. The same thing can happen with double
initialisations - the compiler won't warn about assigning a double that can't actually be represented exactly.
The numeric value on the right of the "=" when initialising a floating point number is known as a "real-literal".
The C# Standard says this about converting the value of a real-literal to a floating point value:
The value of a real literal of type float or double is determined by using the IEEE “round to nearest” mode.
This rounding is performed without provoking a compile error.
CodePudding user response:
Your understanding is correct, the f
at the end of the number indicates that it's a float
, so it will be considered as a float
and when you assign this float
value to a float
variable, you will not get conversion errors.
If there is no f
at the end of the number having decimals, then, by default, the value is handled as a double
and once you assign this double
value to a float
variable, you get an error because of potential data loss.
Read more here: https://answers.unity.com/questions/423675/why-is-there-sometimes-an-f-behinf-a-number.html