java - 类型转换与使用 valueOf

标签 java casting standards primitive

我需要将一个 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 作为扩大转换。

然而,在 longdouble 的情况下存在风险,主要风险是并非 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/

相关文章:

java - Android 用户界面停止响应

java - 如何在netbeans中添加java类路径

c - 空指针转换为其他指针类型 T 的行为与 T 不同

c++ - 将 unsigned char* 转换为 std::string

c - 严格别名和指向 union 字段的指针

c - 句法酸涩

针对本地 SASL 的 Java 身份验证

jvm - 在 mac "JAVA_HOME is not defined correctly"上构建 openjdk

java - Java中什么时候调用对象类型而不是对象的方法,特别是在静态绑定(bind)中?

c - C标准支持的平台列表