可能导致精度或幅度损失的 Java 隐式强制转换? [复制]
Posted
技术标签:
【中文标题】可能导致精度或幅度损失的 Java 隐式强制转换? [复制]【英文标题】:Java implicit casts that can lead to precision or magnitude loss? [duplicate] 【发布时间】:2012-12-06 16:23:24 【问题描述】:我最近learned,在将一些 Java 代码转换为 C# 时,Java 的增量运算符 '+=' 隐式转换为 LHS 的类型:
int i = 5;
long lng = 0xffffffffffffL; //larger than Int.MAX_VALUE
i += lng; //allowed by Java (i==4), rejected by C#
相当于:(details here)
int i = 0;
long lng = 0xffffffffffffL;
i = (int)(i + lng);
从而默默地造成损失幅度的机会。
C# 在编译时对此更加认真:Cannot convert source type long to target type int.
Java 是否允许其他类似的情况?
【问题讨论】:
可能是因为这不是关于 C# 的问题,它只是指它??当人们仅仅因为他们在问题中提到它而包含[java]
时,我发现它很烦人(但我不反对)。
@Peter 好的,你可能有道理。当我问这个问题时,我的心态非常 C#-y(在修复从 Java 转换而来的 C# 代码方面非常努力)。从未想过从读者的角度添加标签 :) [C# 标签已删除]
我只是在这里猜测。当人们投反对票时,我觉得很烦,但没有评论为什么。这就像告诉你;我觉得你做错了什么,但我没有告诉你是什么,或者我什至不知道这是什么。 ;)
@Peter 所以...嗯,为什么要删除你的答案?
虽然在我给出的示例中它很相似,但它与隐式强制转换不同。 Meriton 指出你不能给它超出范围的值,我注意到你不能写 byte b = 1.0;
但你可以写 b += 1.0;
【参考方案1】:
long 可以提升为 float 或 double,这会导致精度损失:
public static void main(String[] args)
float f = Long.MAX_VALUE;
double d = Long.MAX_VALUE;
System.out.println(Long.MAX_VALUE);
System.out.println(f);
System.out.println(d);
打印
9223372036854775807
9.223372E18
9.223372036854776E18
不过,我怀疑 C# 也是这样做的。
除了你已经提到的复合赋值运算符之外,我相信这些都是隐式转换可以改变值的所有情况。
【讨论】:
从float
到double
的转换可能会使排名发生数百或几个数量级的变化。给定float f=1E20; float f2=f*f; double d = 1E300;
,f2
和(float)d
之间的比较将正确地认为这些值无法区分。另一方面,比较d
和(double)f2
将表明d
比f2
小,即使它应该大240 个数量级。
您的示例无法支持您的主张,因为它使用了 explicit 转换,该转换可以(并且在这种情况下确实)更改了值。具体来说,我们有((float) d) != d
和((double) f2) == f2
。以上是关于可能导致精度或幅度损失的 Java 隐式强制转换? [复制]的主要内容,如果未能解决你的问题,请参考以下文章