声明浮动,为什么默认类型为double? [英] Declaring floats, why default type double?

查看:144
本文介绍了声明浮动,为什么默认类型为double?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我很好奇为什么浮动文字必须如此声明:

I am curious as to why float literals must be declared as so:

float f = 0.1f;

而不是

float f = 0.1;

为什么默认类型为double,为什么编译器不能推断它是一个浮点数看着作业的左侧?谷歌只会出现默认值的解释,而不是原因。

Why is the default type a double, why can't the compiler infer that it is a float from looking at the leftside of the assignment? Google only turns up explanation on what the default values are, not why they are so.

推荐答案


为什么默认类型是double?

Why is the default type a double?

这个问题最适合Java语言的设计者。他们是唯一知道为什么做出语言设计决定的真实原因的人。但是我希望推理有以下几点:

That's a question that would be best asked of the designers of the Java language. They are the only people who know the real reasons why that language design decision was made. But I expect that the reasoning was something along the following lines:

他们需要区分两种类型的文字,因为它们确实意味着不同的价值......来自a数学视角。

They needed to distinguish between the two types of literals because they do actually mean different values ... from a mathematical perspective.

假设他们将浮动作为文字的默认值,请考虑此示例

Supposing they made "float" the default for literals, consider this example

// (Hypothetical "java" code ... )
double d = 0.1;
double d2 = 0.1d;

在上面, d d2 实际上会有不同的值。在第一种情况下,低精度 float 值在赋值时转换为更高精度的 double 值。但是你无法恢复那里没有的精确度。

In the above, the d and d2 would actually have different values. In the first case, a low precision float value is converted to a higher precision double value at the point of assignment. But you cannot recover precision that isn't there.

posit 这两种语句既合法又意味着不同的语言设计事情是一个不好的想法......考虑到第一个陈述的实际含义与自然含义不同。

I posit that a language design where those two statements are both legal, and mean different things is a BAD idea ... considering that the actual meaning of the first statement is different to the "natural" meaning.

按照他们做的方式做它:

By doing it the way they've done it:

double d = 0.1f;
double d2 = 0.1;

既合法又有意思。但是在第一个声明中,程序员的意图是明确的,第二个声明是自然意义是程序员得到的。在这种情况下:

are both legal, and mean different things again. But in the first statement, the programmer's intention is clear, and the second statement the "natural" meaning is what the programmer gets. And in this case:

float f = 0.1f;
float f2 = 0.1;    // compilation error!

...编译器发现不匹配。

... the compiler picks up the mismatch.


我猜使用浮点数是例外而不是规则(使用双打)而不是现代硬件所以在某些时候它会有意义假设用户在写入时想要0.1f float f = 0.1;



<他们可以已经这样做了。但是问题出现了一组有效的类型转换规则......而且很简单,你不需要Java实际的学位来实际理解。 0.1 意味着不同情况下的不同内容会令人困惑。并考虑一下:

They could do that already. But the problem is coming up with a set of type conversion rules that work ... and are simple enough that you don't need a degree in Java-ology to actually understand. Having 0.1 mean different things in different context would be confusing. And consider this:

void method(float f) { ... }
void method(double d) { ... }

// Which overload is called in the following?
this.method(1.0);

编程语言设计很棘手。一个区域的变化可能会对其他区域产生影响。

Programming language design is tricky. A change in one area can have consequences in others.

更新以解决一些问题by @supercat。

UPDATE to address some points raised by @supercat.


@supercat:鉴于上述重载,将为方法(16777217)调用哪个方法?这是最好的选择吗?

@supercat: Given the above overloads, which method will be invoked for method(16777217)? Is that the best choice?

我错误地评论了...编译错误。实际上答案是方法(浮点数)

I incorrectly commented ... compilation error. In fact the answer is method(float).

JLS说:


15.12.2.5。选择最具体的方法

如果多个成员方法都可访问且适用于
方法调用,则必须选择一个为运行时方法调度提供
描述符。 Java编程
语言使用选择最具体方法的规则。

If more than one member method is both accessible and applicable to a method invocation, it is necessary to choose one to provide the descriptor for the run-time method dispatch. The Java programming language uses the rule that the most specific method is chosen.

...

[符号m1和m2表示适用的方法。]

[The symbols m1 and m2 denote methods that are applicable.]

[if] m2不是通用的,m1和m2适用于严格
松散调用,以及其中m1具有形式参数类型S1,...,Sn
和m2具有形式参数类型T1,...,Tn,对于所有i,类型Si对于参数ei比Ti更具特定于
( 1≤i≤n,n = k)。

[If] m2 is not generic, and m1 and m2 are applicable by strict or loose invocation, and where m1 has formal parameter types S1, ..., Sn and m2 has formal parameter types T1, ..., Tn, the type Si is more specific than Ti for argument ei for all i (1 ≤ i ≤ n, n = k).

...

以上条件是唯一的一种方法
可能比另一种方法更具体的情况。

The above conditions are the only circumstances under which one method may be more specific than another.

如果S<:T,则类型S比任何表达式的类型T更具体
(§4.10)。

A type S is more specific than a type T for any expression if S <: T (§4.10).

在这种情况下,我们正在比较方法(浮动)方法(双倍)这些都适用于该呼叫。由于 float <: double ,因此更具体,因此方法(浮动)将被选中。

In this case, we are comparing method(float) and method(double) which are both applicable to the call. Since float <: double, it is more specific, and therefore method(float) will be selected.


@supercat:这种行为可能会导致问题,例如:表达式
int2 =(int)Math.Round(int1 * 3.5) long2 = Math.Round(long1 * 3.5) 替换为 int1 =(int)Math.Round(int2 * 3) long2 = Math.Round(long1 * 3)

此更改看起来无害,但前两个表达式是
更正 613566756 2573485501354568 后两个
5592405 以上失败[最后一个完全虚假超过
715827882 ]。

The change would look harmless, but the first two expressions are correct up to 613566756 or 2573485501354568 and the latter two fail above 5592405 [the last being completely bogus above 715827882].

如果你是谈论一个人做出这种改变......好吧。

If you are talking about a person making that change ... well yes.

然而,编译器不会在你背后做出改变。例如, int1 * 3.5 的类型为 double int 转换为 double ),因此您最终调用 Math.Round(double)

However, the compiler won't make that change behind your back. For example, int1 * 3.5 has type double (the int is converted to a double), so you end up calling the Math.Round(double).

作为一般规则,Java算法将隐式地从较小​​转换为较大数字类型,但不会从较大转换为较小。

As a general rule, Java arithmetic will implicitly convert from "smaller" to "larger" numeric types, but not from "larger" to "smaller".

但是,你仍然需要小心,因为(在你的舍入示例中):

However, you do still need to be careful since (in your rounding example):


  • 整数和浮点的乘积可能无法以足够的精度表示,因为(例如) float 的精度比 int <更少/ code>。

  • the product of a integer and floating point may not be representable with sufficient precision because (say) a float has fewer bits of precision than an int.

Math.round(double)的结果投射到一个整数类型可以导致转换为整数类型的最小/最大值。

casting the result of Math.round(double) to an integer type can result in conversion to the smallest / largest value of the integer type.

但所有这些都说明了编程语言中的算术支持是棘手的,并且对于新的或非战争来说存在不可避免的问题程序员。

But all of this illustrates that arithmetic support in a programming language is tricky, and there are inevitable gotcha's for a new or unwary programmer.

这篇关于声明浮动,为什么默认类型为double?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆