我需要将一个 long 变量转换为 double。 long 变量的值不是文字,它是另一个方法返回的值,比如 System.currentTimeMillis()。我需要将它转换为 double 以进行十进制计算,例如将毫秒转换为秒,而不丢失小数部分。
因此,一种方法是使用 Double.valueOf(),然后将 .doubleValue() 输出除以 1000。
long then = System.currentTimeMillis();
long now = System.currentTimeMillis();
double timeElapsed = Double.valueOf(now - then).doubleValue() / 1000;
这是正确的方法吗?或者我应该简单地按如下方式转换它们?
double timeElapsed = ((double) now - (double) then) / 1000;
我想知道哪种方法最好。
请分享您的意见/建议。
谢谢。
最佳答案
There is no Double.valueOf(long)
.
在您的第一个示例中实际发生的是 now - then
正在计算,结果是 long
,然后它被隐式转换为 double
并传递给 Double.valueOf(double)
。基本上是这样的:
double timeElapsed = Double.valueOf((double)(now - then)).doubleValue() / 1000;
如您所见,这毫无用处!另请注意,自动拆箱会自动将 Double
转换为 double
,因此 doubleValue()
也是毫无用处。
强制转换是正确的做法:
double timeElapsed = (double)(now - then) / 1000.0;
其中,只要您使用 1000.0
而不是 1000
,就等同于:
double timeElapsed = (now - then) / 1000.0;
Double.valueOf(double)
的目的,顺便说一下,只是给你一个显式装箱 double
并将其转换为 Double
如果需要的话。 doubleValue()
的目的正好相反。两者都不适合您的情况。 (这通常适用于原始包装类上的所有 valueOf
/*Value
方法。)
顺便说一下,为了降低精度损失的风险(在您的情况下风险不大,但通常情况下),通常执行上述操作比:
double timeElapsed = ((double)now - (double)than) / 1000.0;
可以在 here 中找到有关示例中发生的情况的一些解释。允许扩大基元转换自动发生,并且 JLS 将 long
分类为 double
作为扩大转换。
然而,在 long
到 double
的情况下存在风险,主要风险是并非 long
的所有值都可以表示通过 double
,信息可能会在转换中悄无声息地丢失。考虑以下简单测试(在 http://ideone.com/zCmQzg 运行):
for (long a = 1; ; a *= 7) {
long x = Double.valueOf(a).longValue();
if (x != a) {
System.out.println("Conversion fails at input=" + a + " output=" + x);
break;
}
}
此测试将在某些值时失败(例如 Double.valueOf(11398895185373143L)
不是您所期望的),作为 long
的 base-2 尾数得到保证> 超出了 double
的尾数范围。另一个简单的测试:
long x = 123456789123456789L;
System.out.println(x);
System.out.println(String.format("%20f", Double.valueOf(x))); // implicit
System.out.println(String.format("%20f", (double)x)); // explicit, same thing
输出:
123456789123456789
123456789123456784.000000
123456789123456784.000000
注意最后一位数字。
当您将整数转换为 double 时,这种危险任何都存在,包括在我上面的示例中 - 然而,值得注意的是,因为将 long
传递给 Double.valueOf()
,在我看来,比其他人更容易措手不及。
关于java - 类型转换与使用 valueOf,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25133157/