简体   繁体   English

为什么int / byte / short / long可以在没有类型转换的情况下转换为float / double,反之亦然

[英]Why can int/byte/short/long be converted to float/double without typecasting but vice-versa not possible

My code goes like this -- 我的代码是这样的 -

public void abc{     
 long a=1111;
 float b=a; // this works fine even though this is narrowing conversion
 long c=b;// this gives compilation error
}

Can you explain why this is happening? 你能解释一下为什么会这样吗?

The reason is specified in JLS 5.1.2 : It says that : long to float or double is a widening conversion. 原因在JLS 5.1.2中指定:它表示: long to float或double是一个扩展转换。
Whereas, float to byte, short, char, int, or long is narrowing conversion. float,byte,short,char,int或long缩小了转换。
That's why 这就是为什么
float b=a; is working fine in your program , since it is widening conversion. 在你的程序中运行正常,因为它正在扩大转换。
And long c=b; long c=b; is showing compilation error since it is a narrowing conversion. 显示编译错误,因为它是一个缩小的转换。

When you convert from an integral type to a floating point one, it is always clear what you want to do: you change number's representation, but you keep the same number. 当您从整数类型转换为浮点类型时,始终清楚您要执行的操作:更改数字的表示形式,但保留相同的数字。

Converting from floating point to integral types, on the other hand, has some ambiguity: it is not clear what you would like to do with the fractional part. 另一方面,从浮点转换为整数类型有一些模糊性:不清楚您想对小数部分做什么。 You may want to 你可能想要

  • Truncate the fractional part, 截断小数部分,
  • Perform mathematical rounding, or 执行数学舍入,或
  • Round the number up. 将数字向上舍入。

That's why the language asks you to be specific about what you want to do when converting floating-point numbers to integral types. 这就是为什么语言要求您具体说明在将浮点数转换为整数类型时要执行的操作。

Because a long can be represented as a float , but any float cannot be represented as a long . 因为long可以表示为float ,但任何float都不能表示为long That is mathematic not Java. 这是数学而不是Java。

Here you could add a cast to force the compilation. 在这里你可以添加一个强制转换来强制编译。 Of course, you could lose precision since you are converting a float to a long . 当然,由于您将float转换为long ,因此可能会丢失精度。

long c = (long) b;

The conversion rules are based on the range of numbers the data types can represent. 转换规则基于数据类型可以表示的数字范围。 The range allowed by long is contained in the range allowed by float , so an implicit conversion is allowed despite the obvious loss of precision: long stores 64 bits while float is only 32 so the conversion throws away half of the data. long允许的范围包含在float允许的范围内,因此尽管明显损失了精度,仍允许隐式转换:long存储64位而float只有32,因此转换会丢弃一半的数据。

I Java implicit widening conversions are allowed, but not narrowing. 我允许Java隐式扩展转换,但不允许缩小。 That basically means that it is ok to convert to any datatype that can hold as large or larger values the the original data type without explicitly casting the data. 这基本上意味着可以转换为任何数据类型,该数据类型可以保存原始数据类型的大或大值,而无需显式地转换数据。 This does however mean that you might lose precision. 但这确实意味着您可能会失去精确度。

ex. 恩。

long original = Long.MAX_VALUE-1;
float f = original;
long result = (long) f;
System.err.println(original);
System.err.println(f);
System.err.println(result);

See more at JLS 5.1.2. 有关详细信息,请参阅JLS 5.1.2。 Widening Primitive Conversion 扩大原始转换

Take a look at this 看看这个

byte
1 signed byte (two's complement). Covers values from -128 to 127.

short
2 bytes, signed (two's complement), -32,768 to 32,767   

int   
4 bytes, signed (two's complement). -2,147,483,648 to 2,147,483,647.
Like all numeric    types ints may be cast into other numeric types
(byte, short, long, float, double). When lossy casts are done (e.g.
int to byte) the conversion is done modulo the length of the smaller
type.

long  
8 bytes signed (two's complement). Ranges from
-9,223,372,036,854,775,808 to +9,223,372,036,854,775,807.

float 
4 bytes, IEEE 754. Covers a range from 1.40129846432481707e-45
to 3.40282346638528860e+38 (positive or negative). 
Like all numeric types floats may be cast into other numeric types
(byte, short, long, int, double). When lossy casts to integer types
are done (e.g. float to short) the fractional part is truncated and
the conversion is done modulo the length of the smaller type.

double 
8 bytes IEEE 754. Covers a range from 4.94065645841246544e-324d
to 1.79769313486231570e+308d (positive or negative).

Now you can realize if we are going to represent some float and double values in others. 现在你可以意识到我们是否要在其他人中代表一些浮点值和双值。 part of the original number(float or double) will missing. 原始数字(浮点数或双数)的一部分将丢失。 so casting is not possible in that case 所以在这种情况下不可能进行铸造

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM