Java:为什么在浮点型字面量中需要指定“f”?

42

为什么在浮点数字面量中需要指定后缀f


4
否则,它就不会是一个浮点数字面量。 - SLaks
1
虽然这是关于C语言的,但你可能会喜欢这个有关浮点常量微妙之处的测验。我相信其中的五个问题在Java中的表现应该完全一样。http://blog.frama-c.com/index.php?post/2011/11/08/Floating-point-quiz - Pascal Cuoq
3个回答

52
否则默认为double,这是比float更常用的浮点类型。
来自Java语言规范,第3.10.2节

如果浮点字面量后缀为ASCII字母F或f,则其类型为float;否则它的类型为double,并且可以选择使用ASCII字母D或d作为后缀(§4.2.3)。

(个人而言,我希望没有默认值,在所有情况下都清晰明了,但这是另一回事。)

1
但是如果默认为另一种类型,为什么还要有一个类型的减速呢?我知道double只是64位浮点数,但这背后是否有更深层次的原因呢? - stackoverflow
2
@stackoverflow:你是什么意思?字面量的类型与您使用的变量的类型有些独立。例如,您可以使用float字面量并将其分配给double变量。在大多数情况下,表达式的类型与其使用的上下文无关。(有一些情况下,泛型的类型是推断出来的,但那是一个特殊情况。) - Jon Skeet
1
Java支持在将字面量赋值给基本类型时进行缩小转换。这就是为什么您可以拥有float f = 1.0;,即使1.0是一个double类型。我猜这是被支持的,因为它是明确无误的 - 不像使用带有方法调用的字面量,例如。 - McDowell
2
@McDowell,除了 float f = 1.0; 不可编译之外。你需要一个显式转换:float f = (float) 1.0; - aioobe

37

由于未加后缀的浮点型字面量是双精度类型,而舍入意味着即使小字面量被舍入为float和double时也可能具有不同的值。可以在以下示例中观察到这一点:

float f = (float) 0.67;
if(f == 0.67) 
  System.out.print("yes");
else 
  System.out.print("no");  

这将输出no,因为当0.67四舍五入为浮点数时,其值与四舍五入为双精度浮点数时不同。 另一方面:

float f = (float) 0.67;
if(f == 0.67f) 
  System.out.print("yes");
else 
  System.out.print("no");

… 输出yes

编辑
第二个例子:

if(0.67 == 0.67f) 
  System.out.print("Equal");
else 
  System.out.print("Not Equal");  

…输出Not Equal


5
有两种浮点数类型可以表示为例如100.0。只有一种可以作为默认值。由于其精度有限,float是一种极其专业化的类型。通常情况下使用double,因此它是适当的默认值。
在现代处理器上,float和double具有类似的计算性能。仅在需要有限精度的性能关键情况下使用float,如大型数组。使用float会使得一个缓存行中可容纳的浮点数值翻倍。即使如此,确定float是否为给定计算提供足够精度的问题也很少是简单的。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接