简体   繁体   中英

C# explanation of the "f" keyword for a float vs implicit and explicit conversions

So I don't really get the conversion from a float to a double eg:

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.

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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM