在java中将int转换为double,然后再转换回int

在java中将int转换为double,然后再转换回int,java,type-conversion,primitive,Java,Type Conversion,Primitive,快速提问 这永远是真的吗 int i = ...; double d = i; if (i == (int) d) ... 或者我需要四舍五入来确定 if (i == Math.round(d)) ... 是的,所有可能的int值都可以安全地往返到double 您可以使用以下代码进行验证: for (int i = Integer.MIN_VALUE; ; i++) { double d = i; if (i != (int) d) {

快速提问

这永远是真的吗

int i = ...;
double d = i;
if (i == (int) d) ...
或者我需要四舍五入来确定

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

是的,所有可能的
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;
        }
    }
请注意,我没有对循环使用普通的
,因为它会跳过
Integer.MAX\u值
或无限期循环


请注意,对于
int
/
float
long
/
double
,这一点是不正确的

如果您的计算机速度较慢,或者没有时间运行循环来检查自己,Java语言规范的相关部分如下:

以下19种基元类型的特定转换称为扩展基元转换:

  • 字节到短、int、long、float或double
  • 短到整数、长到浮点或双精度
  • 字符到int、long、float或double
  • int到long、float或double
  • 长到漂浮或翻倍
  • 浮动至双倍
加宽基元转换不会丢失有关数值总体大小的信息事实上,从一个整数类型到另一个整数类型以及从浮点到双精度的转换完全不会丢失任何信息数值被准确地保存。[……]


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

Joachim解决方案的变体

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

@delnan:使用该条件将跳过对
整数的测试。MAX_VALUE
@JoachimSauer谢谢您的回答@delnan,检查过了,在我的电脑上运行20秒computer@JoachimSauer嗯,对于
int/float
long/double
来说,更多的是容量问题,而不是舍入,对吗?@JustYo,是容量问题导致了表示中的舍入错误。它通常被称为舍入误差。@JustYo,浮动在2^24左右。e、 g.
int i=16777217;浮点数f=i;int d=(int)f现在
d
是16777216!我检查了转换
intfloat
,它在
-2147483647
上刹车。往返后变为
-2147483648
右,
float->int
,但这是一种可能丢失信息的变窄转换。
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