例:
float timeRemaining = 0.58f;
为什么f在此数字末尾需要?
例:
float timeRemaining = 0.58f;
为什么f在此数字末尾需要?
double & int。
Answers:
您的浮动声明包含两个部分:
timeRemaining的类型为float。0.58给此变量。该问题出现在第2部分中。
右侧将自行评估。根据C#规范,包含不带后缀的小数点的数字将解释为double。
因此,我们现在有了一个double要分配给type变量的值float。为此,必须存在从double到的隐式转换float。没有这种转换,因为您可能(在这种情况下确实)会在转换中丢失信息。
原因是编译器使用的值并不是真正的0.58,而是最接近0.58的浮点值,即对于0.57999999999999978655962351581366 ...double和对于0.57999994605757796478271484375float。
严格来说,f不需要。您可以f通过将值强制转换为来避免使用后缀float:
float timeRemaining = (float)0.58;
(float) 0.58工作?您之前说过,没有转换,因为可能会丢失信息,那么转换将如何起作用?
2.4在其他任何地方都被解释为双精度型。2.不允许隐式变窄转换(如从double到float)。如果您想对这些规则作例外处理,那么您必须有充分的理由。节省1个击键可能不够好。
因为有几个数字类型,编译器可以用它来表示该值0.58:float,double和decimal。除非您同意编译器为您选择一个,否则您必须消除歧义。
的文档double指出,如果您自己未指定类型,则编译器将始终选择double任何实数值文字的类型:
默认情况下,赋值运算符右侧的实数值文字被视为double。但是,如果要将整数视为双精度数,请使用后缀d或D。
附加后缀f会创建一个float;后缀d创建一个double; 后缀m创建一个decimal。所有这些都可以大写。
但是,这仍然不足以解释为什么它不能编译:
float timeRemaining = 0.58;
答案的缺失部分是从double 0.58到的转换float timeRemaining可能会丢失信息,因此编译器拒绝隐式应用它。如果添加显式转换,则会执行转换;如果添加f后缀,则无需转换。在这两种情况下,代码都将编译。
int和一个用于)过于昂贵double。
double a = 0.69f;?
float为double。
问题在于,.NET为了允许进行涉及float和的某些类型的隐式操作double,需要明确指定在涉及混合操作数的所有情况下应发生的情况,或者允许在一种类型之间执行隐式转换。仅方向 微软选择跟随Java的发展方向,以允许偶尔偏向于精度的方向,但是却经常牺牲正确性并通常造成麻烦。
在几乎所有情况下,取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,254,740,992(减少了536,870,913)。但是,通常,将double某个数量的最佳表示转换为float可能会产生最佳float表示,或者本质上是相同的两种表示之一。
注意,这种理想的行为甚至在极端情况下也适用。例如,float数量10 ^ 308float的最佳double表示形式与通过转换该数量的最佳表示形式获得的表示形式相匹配。同样,最佳float表示形式10 ^ 309与float通过转换该double数量的最佳表示形式获得的表示形式相匹配。
不幸的是,在不需要显式转换的方向上进行转换的准确性很少。将float值的最佳表示形式转换为double几乎不会产生double与该值的最佳表示形式特别接近的任何信息,并且在某些情况下,结果可能相差数百个数量级(例如,将float10 ^ 40的最佳表示形式转换为double将产生一个比最佳double表示形式10 ^ 300大的值。
,,转换规则就是它们的本质,因此,在“安全”方向上转换值时,必须忍受愚蠢的类型转换和后缀,并且要注意在危险方向上隐式的类型转换,这经常会产生假结果。
double。