Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/338.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java中基本整数类型的不一致行为_Java_Primitive Types_Scjp - Fatal编程技术网

Java中基本整数类型的不一致行为

Java中基本整数类型的不一致行为,java,primitive-types,scjp,Java,Primitive Types,Scjp,有人能像我五岁一样向我解释一下,为什么在Java中表示整数的四种基本类型中,有两种会有不同的行为?所有四个都是有符号的,它们都使用最高有效位作为符号位,那么为什么字节和短字符的行为正常,而int和长字符的行为奇怪呢?oracle文档中解释这一点的片段将是完美的 byte a = (byte) (Math.pow(2, 7)-1); //127 - as expected short b = (short) (Math.pow(2, 15)-1); //32767 - as expected in

有人能像我五岁一样向我解释一下,为什么在Java中表示整数的四种基本类型中,有两种会有不同的行为?所有四个都是有符号的,它们都使用最高有效位作为符号位,那么为什么字节和短字符的行为正常,而int和长字符的行为奇怪呢?oracle文档中解释这一点的片段将是完美的

byte a = (byte) (Math.pow(2, 7)-1); //127 - as expected
short b = (short) (Math.pow(2, 15)-1); //32767 - as expected
int c = (int) (Math.pow(2, 31)-1); //2147483647 - as expected
long d = (long) (Math.pow(2, 63)-1); //9223372036854775807 - as expected

a = (byte) (Math.pow(2, 7)); //-128 - as expected
b = (short) (Math.pow(2, 15)); //-32768 - as expected
c = (int) (Math.pow(2, 31)); //2147483647 - why not '-2147483648'?
d = (long) (Math.pow(2, 63)); //9223372036854775807 - why not '-9223372036854775808'?

a = (byte) (Math.pow(2, 8)); //0 - as expected
b = (short) (Math.pow(2, 16)); //0 - as expected
c = (int) (Math.pow(2, 32)); //2147483647 - why not '0'?
d = (long) (Math.pow(2, 64)); //9223372036854775807 - why not '0'?
我正在使用Oracle的JavaSE1.7 for Windows。操作系统是Windows7专业版SP1

java version "1.7.0_45"
Java(TM) SE Runtime Environment (build 1.7.0_45-b18)
Java HotSpot(TM) 64-Bit Server VM (build 24.45-b08, mixed mode)

阅读所有答案并调整代码后进行编辑。
总之,我发现获得期望值的唯一方法是使用BigInteger。移位运算符对于字节、短字符和整数都很有效,但对于长字符,我只在一次故障时使用它

byte a = (byte) ((1l << 7) - 1); //127 - as expected
short b = (short) ((1l << 15) - 1); //32767 - as expected
int c = (int) (1l << 31) - 1; //2147483647 - as expected
long d = (1l << 63) - 1; //9223372036854775807 - as expected

a = (byte) (1l << 7); //-128 - as expected
b = (short) (1l << 15); //-32768 - as expected
c = (int) 1l << 31; //-2147483648 - as expected
d = 1l << 63; //-9223372036854775808 - as expected

a = (byte) (1l << 8); //0 - as expected
b = (short) (1l << 16); //0 - as expected
c = (int) (1l << 32); //0 - as expected
d = 1l << 64; //1 instead of 0, probably because of the word length limitation      
感谢大家的大力帮助
Math.pow()
返回一个
double
,然后在转换为整数类型时对其进行四舍五入。
double
显然比使其溢出所需的精度要低得多。

讨论了cast使用的缩小原语转换的行为

否则,以下两种情况之一必须为真:

该值必须太小(大数值的负值或负无穷大),并且第一步的结果是int或long类型的最小可表示值

值必须太大(大数值的正值或正无穷大),并且第一步的结果是int或long类型的最大可表示值

(强调矿山)

这就是为什么
(int)(Math.pow(2,32))变为
Integer.MAX\u值
(long)(Math.pow(2,64))
变为
long.MAX\u值

具有指导意义:

public class PowTest {
    public static void main(String[] argv) {
        double powResult = Math.pow(2.0,31.0);
        int powInt = (int) powResult;
        long powLong = (long) powResult;
        int longInt = (int) powLong;
        System.out.println("Double = " + powResult + ", int = " + powInt + ", long = " + powLong + ", longInt = " + longInt);
    }
}
结果:

C:\JavaTools>java PowTest
Double = 2.147483648E9, int = 2147483647, long = 2147483648, longInt = -2147483648

double->int转换是四舍五入的。long->int转换被截断。

try 2注意,该部分专门讨论浮点到整数与整数类型之间的比较。+1:在阅读JLS Targetman发布的摘录时,我考虑的是完全相同的测试用例:)事实上,如果我理解正确,这就是为什么我在byte和short中有负数。Double四舍五入为int,然后被截断为byte和short,对吗?
C:\JavaTools>java PowTest
Double = 2.147483648E9, int = 2147483647, long = 2147483648, longInt = -2147483648