Java 声明浮点,为什么默认类型为double?
我很好奇为什么必须声明浮点文字:Java 声明浮点,为什么默认类型为double?,java,Java,我很好奇为什么必须声明浮点文字: float f = 0.1f; 而不是 float f = 0.1; 为什么默认类型是double,为什么编译器不能从赋值的左侧推断它是float?谷歌只给出了默认值是什么的解释,而没有解释为什么会这样 为什么默认类型是double 这是一个最好向Java语言设计者提出的问题。他们是唯一知道做出语言设计决定的真正原因的人。但我认为原因大致如下: 他们需要区分这两种文字,因为它们实际上意味着不同的值。。。从数学的角度来看 假设他们对文本进行了“浮点”默认,考虑
float f = 0.1f;
而不是
float f = 0.1;
为什么默认类型是double,为什么编译器不能从赋值的左侧推断它是float?谷歌只给出了默认值是什么的解释,而没有解释为什么会这样
为什么默认类型是double
这是一个最好向Java语言设计者提出的问题。他们是唯一知道做出语言设计决定的真正原因的人。但我认为原因大致如下:
他们需要区分这两种文字,因为它们实际上意味着不同的值。。。从数学的角度来看
假设他们对文本进行了“浮点”默认,考虑这个例子
// (Hypothetical "java" code ... )
double d = 0.1;
double d2 = 0.1d;
在上面的例子中,d
和d2
实际上具有不同的值。在第一种情况下,低精度浮点值
在赋值点转换为高精度双精度值。但你无法恢复没有的精确度
我认为,如果语言设计中这两种说法都是合法的,并且意思不同,那是个坏主意。。。考虑到第一句话的实际含义不同于“自然”含义
按照他们的方式来做:
double d = 0.1f;
double d2 = 0.1;
两者都是合法的,而且意义不同。但是在第一条语句中,程序员的意图是明确的,而第二条语句的“自然”含义是程序员得到的。在这种情况下:
float f = 0.1f;
float f2 = 0.1; // compilation error!
。。。编译器将拾取不匹配项
我猜在现代硬件中使用浮点数是个例外,而不是规则(而是使用双精度浮点数),因此在某些情况下,假设用户在编写float f=0.1时打算使用0.1f是有意义的代码>
他们已经可以这样做了。但问题是出现了一套有效的类型转换规则。。。而且非常简单,您不需要获得Java语言学学位就可以真正理解。让0.1
在不同的上下文中表示不同的内容会让人困惑。考虑这个问题:
void method(float f) { ... }
void method(double d) { ... }
// Which overload is called in the following?
this.method(1.0);
编程语言设计很棘手。一个领域的变化可能会对其他领域产生影响
更新以解决@supercat提出的一些问题
@supercat:给定上述重载,将为方法(16777217)调用哪个方法?这是最好的选择吗
我错误地评论了。。。编译错误。事实上,答案是方法(float)
联合联络小组说:
如果多个成员方法可访问且适用于
方法调用时,必须选择一个来提供
运行时方法分派的描述符。Java编程
语言使用的规则是选择最具体的方法
[符号m1和m2表示适用的方法。]
[如果]m2不是通用的,m1和m2通过严格或
松散调用,其中m1具有形式参数类型S1,…,Sn
m2有形式参数类型T1,…,Tn,类型Si更多
所有i(1)的参数ei比Ti具体≤ 我≤ n、 n=k)
上述条件是唯一可以使用一种方法的情况
可能比另一个更具体
对于任何表达式,S型都比T型更具体。如果SHa,这只是冰山一角,我的朋友
来自其他语言的程序员当然不介意在文字中添加一点F
,而不是:
SomeReallyLongClassName x = new SomeReallyLongClassName();
相当多余,对吧
确实,为了获得更多的背景知识,您必须与核心Java开发人员自己交谈。但作为一种纯粹的表面解释,需要理解的一个重要概念是表达式是什么。在Java中(我不是专家,所以对此持保留态度),我相信在编译器级别,您的代码是根据表达式进行分析的;因此:
float f
有一个类型,并且
0.1f
还有一个类型(float
)
一般来说,如果要将一个表达式指定给另一个表达式,则类型必须一致。在一些非常特殊的情况下,此规则会被放宽(例如,在引用类型(如Integer
)中装箱一个类似int
的基元);但总的来说,这是正确的
在这种情况下,它可能看起来很愚蠢,但这里有一个非常类似的情况,它看起来并不那么愚蠢:
double getDouble() {
// some logic to return a double
}
void example() {
float f = getDouble();
}
现在在本例中,我们可以看到编译器发现错误是有意义的。getDouble
返回的值将具有64位精度,而f
只能包含32位;因此,如果没有显式强制转换,程序员可能会犯错误
从人类的角度来看,这两种情况明显不同;但我关于表达式的观点是,当代码首先分解为表达式,然后进行分析时,它们是相同的
我确信编译器的作者可以编写一些不那么聪明的逻辑,根据他们被分配到的表达式类型重新解释文本;他们根本没有。与其他功能相比,它可能不值得这么做
对于透视图,很多语言都能够进行类型推断;例如,在C#中,您可以执行以下操作:
var x = new SomeReallyLongClassName();
编译器将根据该赋值推断x
的类型
不过,对于文字而言,C#在这方面与Java相同。float
的精度很低,因此更有趣的问题是;为什么会得到支持?很少有情况下,float
可以使用相同的内存(如果您有数百万个),或者您需要它们来与需要float的对象交换数据
一般来说,使用double
是一种b