C# 为什么在声明浮点数时需要“f”?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11519743/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why is the "f" required when declaring floats?
提问by Thomas
Example:
例子:
float timeRemaining = 0.58f;
Why is the fis required at the end of this number?
为什么f需要在这个数字的末尾?
采纳答案by Jeffrey Sax
Your declaration of a float contains two parts:
您对浮点数的声明包含两部分:
- It declares that the variable
timeRemainingis of typefloat. - It assigns the value
0.58to this variable.
- 它声明变量
timeRemaining的类型为float。 - 它将值分配
0.58给这个变量。
The problem occurs in part 2.
问题出现在第 2 部分。
The right-hand side is evaluated on its own. According to the C# specification, a number containing a decimal point that doesn't have a suffix is interpreted as a double.
右侧是自行评估的。根据 C# 规范,包含没有后缀的小数点的数字被解释为double.
So we now have a doublevalue that we want to assign to a variable of type float. In order to do this, there must be an implicit conversion from doubleto float. There is no such conversion, because you may (and in this case do) lose information in the conversion.
所以我们现在有一个double要分配给类型变量的值float。为了做到这一点,必须有一个从double到的隐式转换float。没有这样的转换,因为您可能(在这种情况下确实会)在转换中丢失信息。
The reason is that the value used by the compiler isn't really 0.58, but the floating-point value closest to 0.58, which is 0.57999999999999978655962351581366... for doubleand exactly 0.579999946057796478271484375 for float.
其原因是由编译器使用的值是不是真正0.58,但最接近0.58浮点值,这是0.57999999999999978655962351581366 ...用于double和准确0.579999946057796478271484375 float。
Strictly speaking, the fis not required. You can avoid having to use the fsuffix by casting the value to a float:
严格来说,这f不是必需的。您可以f通过将值转换为 a来避免使用后缀float:
float timeRemaining = (float)0.58;
回答by Jon
Because there are several numeric types that the compiler can use to represent the value 0.58: float, doubleand decimal. Unless you are OK with the compiler picking one for you, you have to disambiguate.
因为编译器可以使用多种数字类型来表示值0.58:float、double和decimal。除非您同意编译器为您选择一个,否则您必须消除歧义。
The documentation for doublestates that if you do not specify the type yourself the compiler always picks doubleas the type of any real numeric literal:
的文档double指出,如果您自己不指定类型,编译器总是会选择double任何实数文字的类型:
By default, a real numeric literal on the right side of the assignment operator is treated as double. However, if you want an integer number to be treated as double, use the suffix d or D.
默认情况下,赋值运算符右侧的实数值文字被视为双精度值。但是,如果要将整数视为双精度数,请使用后缀 d 或 D。
Appending the suffix fcreates a float; the suffix dcreates a double; the suffix mcreates a decimal. All of these also work in uppercase.
附加后缀f会创建一个float; 后缀d创建一个double; 后缀m创建一个decimal. 所有这些也都适用于大写。
However, this is still not enough to explain why this does not compile:
但是,这仍然不足以解释为什么它不能编译:
float timeRemaining = 0.58;
The missing half of the answer is that the conversion from the double0.58to the floattimeRemainingpotentially loses information, so the compiler refuses to apply it implicitly. If you add an explicit cast the conversion is performed; if you add the fsuffix then no conversion will be needed. In both cases the code would then compile.
答案缺失的一半是从 thedouble0.58到 the的转换floattimeRemaining可能会丢失信息,因此编译器拒绝隐式应用它。如果添加显式转换,则执行转换;如果添加f后缀,则不需要转换。在这两种情况下,代码都会编译。
回答by supercat
The problem is that .NET, in order to allow some types of implicit operations to be carried out involving floatand double, needed to either explicitly specify what should happen in all scenarios involving mixed operands or else allow implicit conversions between the types to be performed in one direction only; Microsoft chose to follow the lead of Java in allowing the direction which occasionally favors precision, but frequently sacrifices correctness and generally creates hassle.
问题是 .NET 为了允许执行涉及float和的某些类型的隐式操作double,需要明确指定在所有涉及混合操作数的场景中应该发生什么,或者允许在一个类型中执行类型之间的隐式转换仅方向;Microsoft 选择跟随 Java 的脚步,允许有时偏向于精确性的方向,但经常牺牲正确性并通常会造成麻烦。
In almost all cases, taking the doublevalue which is closest to a particular numeric quantity and assigning it to a floatwill yield the floatvalue which is closest to that same quantity. There are a few corner cases, such as the value 9,007,199,791,611,905; the best floatrepresentation would be 9,007,200,328,482,816 (which is off by 536,870,911), but casting the best doublerepresentation (i.e. 9,007,199,791,611,904) to floatyields 9,007,199,254,740,992 (which is off by 536,870,913). In general, though, converting the best doublerepresentation of some quantity to floatwill either yield the best possible floatrepresentation, or one of two representations that are essentially equally good.
在几乎所有情况下,取double最接近特定数值float的float值并将其分配给 a将产生最接近相同数量的值。有一些极端情况,例如值 9,007,199,791,611,905;最佳float表示将是 9,007,200,328,482,816(与 536,870,911 相距),但将最佳double表示(即 9,007,199,791,611,904)转换为float9,007,199,259,704,704 与 37 相距)。但是,一般而言,将double某个数量的最佳表示转换为float将产生最佳可能float表示或本质上同样良好的两种表示之一。
Note that this desirable behavior applies even at the extremes; for example, the best floatrepresentation for the quantity 10^308 matches the floatrepresentation achieved by converting the best doublerepresentation of that quantity. Likewise, the best floatrepresentation of 10^309 matches the floatrepresentation achieved by converting the best doublerepresentation of that quantity.
请注意,这种理想的行为即使在极端情况下也适用;例如,float数量 10^308float的最佳double表示与通过转换该数量的最佳表示所获得的表示相匹配。同样,float10^309的最佳表示与float通过转换该double数量的最佳表示所获得的表示相匹配。
Unfortunately, conversions in the direction that doesn't require an explicit cast are seldom anywhere near as accurate. Converting the best floatrepresentation of a value to doublewill seldom yield anything particularly close to the best doublerepresentation of that value, and in some cases the result may be off by hundreds of orders of magnitude (e.g. converting the best floatrepresentation of 10^40 to doublewill yield a value that compares greater than the best doublerepresentation of 10^300.
不幸的是,在不需要显式转换的方向上的转换很少能接近准确。转换的最佳float形式表示的值,以double将很少产生什么特别靠近最好double该值的表示形式,并且在一些情况下,结果可能由数百个数量级的处于关闭状态(例如,最好的转化float的10 ^ 40表示,以double将产生比较大于double10^300的最佳表示的值。
Alas, the conversion rules are what they are, so one has to live with using silly typecasts and suffixes when converting values in the "safe" direction, and be careful of implicit typecasts in the dangerous direction which will frequently yield bogus results.
唉,转换规则就是它们,所以在“安全”方向转换值时必须忍受使用愚蠢的类型转换和后缀,并小心危险方向的隐式类型转换,这会经常产生虚假结果。

