繁体   English   中英

双重到Int没有损失精度

[英]Double to Int without lossy precision

以下声明给出了编译时错误“错误:(19,13)java:不兼容类型:可能从double转换为int的有损转换”

int i1 = 10.0;

// Error:(19, 14) java: incompatible types: possible lossy conversion from double to int

问题1

我理解错误,但编译器可以不推断 - 在这种特殊情况下 - 不会有精度损失?

问题2

如果我显式地将double转换为int然后它编译很好(甚至不是警告),即使我在这个例子中肯定会失去精度

int i2 = (int)9999999999999.999999999;

如果我无法编译第一种情况 - 没有发生丢失 - 那么为什么第二个显式转换示例甚至不会生成编译器警告?

理论上,编译器可以推断#1中的具体示例实际上不会根据文字的值松散精度,但正如您所见 - 它没有。

显式转换信号通知编译器您知道处理它的情况,因此代码实际编译。 但是,大多数IDE都可以配置为在这种情况下发出警告。

double值赋值给int变量需要缩小转换 ,即使该值是编译时常量,因此需要显式转换。

不同之处在于int (或shortchar )恒定值可以被分配给一个byteshort ,或char可变而不铸造,如果常数实际上在各变量值范围配合,以Java语言规范明确地记载,部分5.2。 作业上下文

赋值上下文允许将表达式的值赋值(第15.26节 )给变量; 必须将表达式的类型转换为变量的类型。

赋值上下文允许使用以下之一:

  • 身份转换( §5.1.1

  • 扩展的原始转换(第5.1.2节

  • 扩大参考转换(第5.1.5节

  • 一个拳击转换( §5.1.7 ),可选地后跟一个加宽的引用转换

  • 一个拆箱转换(第5.1.8节 ),可选地后跟一个加宽的基元转换。

如果在应用上面列出的转换后,结果类型是原始类型( §4.8 ),则可以应用未经检查的转换(第5.1.9节 )。

此外, 如果表达式是byteshortcharint类型的常量表达式(第15.28节

  • 如果变量的类型是byteshortchar ,则可以使用缩小的基元转换,并且常量表达式的值可以在变量的类型中表示

  • 如果变量的类型是:则可以使用缩小的基元转换,然后进行装箱转换:

    • Byte和常量表达式的值可在类型byte表示。

    • Short和常量表达式的值可以在short类型中表示。

    • Character和常量表达式的值可在char类型中表示。

回答问题1

根据编译器的精度损失,因为编译器只看到左边有一个int变量,右边有一个double值。 编译器不是那么聪明,以至于在转换为int时10.0不会失去精度。

理论上可以构建编译器以允许编译该语句,但这样做没有实际好处。 几乎没有人写int x = 10.0

回答问题2

实际上,精度有所下降,但为什么编译器不抱怨? 因为你使用了演员。 你写了(int) 这是您向编译器显示您知道自己在做什么。 通过编写演员表,你告诉它你知道可能会失去精确度。

有趣的问题

理论上这可能是有可能的, javac在做的时候不会抱怨:

short s = 12;

即使这里的12int类型的编译时常量,也可以推断出没有精度丢失。 我想这是编译器团队认为最合适的。

好吧当你cast是一个不同的故事时,就像说“相信我,我知道我在做什么”,即使你精确度不高。

暂无
暂无

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

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