【问题标题】:Cast int to double then back to int in java在java中将int转换为double然后回到int
【发布时间】:2011-09-14 13:47:57
【问题描述】:

快速提问。

这总是真的吗?

int i = ...;
double d = i;
if (i == (int) d) ...

或者我需要四舍五入才能确定?

if (i == Math.round(d)) ...

【问题讨论】:

    标签: java type-conversion primitive


    【解决方案1】:

    是的,所有可能的int 值都可以安全地往返于double

    您可以使用以下代码进行验证:

        for (int i = Integer.MIN_VALUE; ; i++) {
            double d = i;
            if (i != (int) d) {
                throw new IllegalStateException("i can't be converted to double and back: " + i);
            }
            if (i == Integer.MAX_VALUE) {
                break;
            }
        }
    

    请注意,我没有使用普通的 for 循环,因为它会跳过 Integer.MAX_VALUE 或无限循环。

    请注意,int/floatlong/double! 的情况不是相同!

    【讨论】:

    • @delnan:使用该条件将跳过对Integer.MAX_VALUE 的测试。
    • @JoachimSauer 感谢您的回答。 @delnan,检查过,它在我的电脑上运行了 20 秒
    • @JoachimSauer 好吧,int/floatlong/double 更多的是容量问题,而不是四舍五入,对吧?
    • @JustYo,它的容量问题导致表示中的舍入错误。它通常被称为舍入误差。
    • @JustYo ,浮动在 2^24 左右爬行。例如int i = 16777217; float f = i; int d = (int)f; 现在 d 是 16777216 !
    【解决方案2】:

    如果您的计算机速度较慢或没有时间运行循环来检查自己,Java 语言规范的相关部分在这里§ 5.1.2 Widening Conversions

    以下 19 种基本类型的特定转换称为加宽基本类型转换:

    • byte 到 short、int、long、float 或 double
    • 短于 int、long、float 或 double
    • char 转换为 int、long、float 或 double
    • int 到 long、float 或 double
    • long to float or double
    • 浮点数加倍

    加宽基元转换不会丢失有关数值整体大小的信息。 确实,从整数类型扩大到另一种整数类型以及从 float 到 double 的转换完全不会丢失任何信息;数值被完全保留。 [...]

    (以下部分 § 5.1.3 Narrowing Primitive Conversions 确保返回的方式 double -> int 也不会丢失任何信息。)

    【讨论】:

    • 我检查了转换int<->float,它在-2147483647 上刹车。往返后变为-2147483648
    • 对,float -> int 不过是一种缩小转换,可能会丢失信息。
    【解决方案3】:

    Joachim 解决方案的变体。

    int i=Integer.MIN_VALUE;
    do {
        if(i != (int)(double) i) throw new AssertionError(i + " != (int)(double) "+i);
    } while(i++ < Integer.MAX_VALUE);
    

    找出导致浮点转换出错的最小值。

    int i = 0;
    do {
        if(i != (int)(float) i) throw new AssertionError(i + " != (int)(float) "+i);
    } while(i++ < Integer.MAX_VALUE);
    

    打印

    java.lang.AssertionError: 16777217 != (int)(float) 16777217
    

    【讨论】:

      猜你喜欢
      • 2013-06-02
      • 1970-01-01
      • 2016-03-18
      • 1970-01-01
      • 2011-05-10
      • 1970-01-01
      • 1970-01-01
      • 2012-06-01
      相关资源
      最近更新 更多