为什么将较大变量转换为较小变量会导致较大变量的模乘以较小变量的范围

Why Type Casting of larger variable to smaller variable results in modulo of larger variable by the range of smaller variable

提问人:Sanku 提问时间:7/2/2016 更新时间:7/18/2022 访问量:2641

问:

最近,当我在 java 中学习类型转换概念时,我看到较大变量到较小变量的类型转换会导致较大变量的模乘以较小变量的范围。谁能详细解释一下为什么会这样,对于任何显式类型转换都是如此吗?

     class conversion {
    public static void main(String args[]) 
    {
        double a = 295.04;
        int  b = 300;
        byte c = (byte) a;
        byte d = (byte) b;
        System.out.println(c + " "  + d);
    } 
}

上面的代码给出了 d 的答案为 44,因为 300 模 256 是 44.请解释为什么会这样,以及 c 的值会发生什么变化?

java 类型转换运算符

评论

0赞 Tahir Hussain Mir 7/2/2016
你有没有想过,如果 b =128,那么模有效,但为什么是负的???检查
0赞 Tahir Hussain Mir 7/2/2016
注释 2:另外,如果 b=255,则模不起作用,也请检查一下。
0赞 Sanku 7/2/2016
是的,我想我知道答案。由于 Byte 数据类型范围是 0 到 127,如果我们越过 127 就会发生溢出,所以它从 -128 倒数到 -1.这就是为什么我们得不到 b=255 的正确答案。
0赞 Stephen C 7/2/2016
“由于 Byte 数据类型范围为 0 到 127” - 不正确。-128 至 +127
1赞 Tahir Hussain Mir 7/2/2016
更好的是了解在显式强制转换的情况下如何切断位。这将使您更好地理解。@SaiSankalp

答:

3赞 Stephen C 7/2/2016 #1

这是一个设计决策,可以追溯到 C 编程语言,也可能可以追溯到 C 的前身。

当您从较大的整数类型转换为较小的整数类型时,会发生什么情况,即顶部位被丢弃。

为什么?最初(和现在)因为这是硬件整数指令支持的。

执行此操作的“其他”逻辑方法(即不是 Java 定义整数缩小的方式)是转换为可在较小类型中表示的最大(或最小)值;例如

    // equivalent to real thin in real java
    // b = (byte) (Math.max(Math.min(i, 127), -128))

将给出 +127 作为 的值。顺便说一句,当您将浮点值转换为整数值并且该值太大时,就会发生这种情况。这就是你的例子中发生的事情。bc


你还说:

上面的代码给出了 d 的答案为 44,因为 300 模 256 是 44。

事实上,正确的计算是:

int d = ((b + 128) % 256) - 128;

这是因为 Java 类型的范围是 -128 到 +127。byte


为了完整起见,上述行为仅在较大的类型是整数类型时才会在 Java 中发生。如果较大的类型是浮点类型,较小的类型是整数类型,则过大或过小(或无穷大)的源值将转换为目标类型的最大或最小可能整数值;例如

double x = 1.0e200;
int i = (int) x;   // assigns 'Integer.MAX_VALUE' to 'i'

NaN 被转换为零。

参考:

评论

0赞 Sanku 7/2/2016
但是在您的示例中,b 的值应该是 44,对吗?
0赞 Mike 7/2/2016
“另一种方式”的解释很好,但是这里的输出表明是(这是),我认为先转换为第一个,然后再转换为一个。至少在 C++ 中是这样完成的。c39295 mod 256 doubleintbyte
0赞 Sanku 7/2/2016
你能解释一下为什么我们需要做模除法才能得到结果吗?
1赞 Stephen C 7/2/2016
@SaiSankalp 1) 否。我描述的是“另一种方式”......Java 没有实现。2) 因为模 256 和“砍掉顶部位”的作用完全相同。
0赞 user207421 7/2/2016
它至少可以追溯到 Algol-60 和 COBOL-60,如果不是最初的 Fortran '57。