Java 奇怪的结果,使短值增加到超过其最大值

Java 奇怪的结果,使短值增加到超过其最大值,java,types,range,short,Java,Types,Range,Short,当我执行这段代码时,它给出s的值为-7616。 为什么会这样?这是因为从int或其他内容转换为short时丢失了数据吗 public static void main(String[] args) { // TODO code application logic here short s=0; int x=123456; int i=8; s +=x; System.out.println(s); }

当我执行这段代码时,它给出s的值为-7616。 为什么会这样?这是因为从int或其他内容转换为short时丢失了数据吗

public static void main(String[] args) {
        // TODO code application logic here
       short s=0;
       int x=123456;
       int i=8;
       s +=x;
       System.out.println(s);

    }

您只是溢出了短路的最大值:

short:short数据类型是16位有符号2的补码 整数。它的最小值为-32768,最大值为 32767(含)。对于byte,同样的准则也适用:您可以 在出现以下情况时,请使用短消息在大型阵列中节省内存: 节省内存实际上很重要

出现这种溢出时发生的情况与此算法等效:

/** Returns an integer which is equal to the short obtained by the ((short) n) conversion */
public static int int2short(int n) {
    int sign      = n > 0 ? 1 : -1;
    int increment = sign * (Short.MAX_VALUE - Short.MIN_VALUE + 1);
    for ( ; n > Short.MAX_VALUE || n < Short.MIN_VALUE ; n -= increment);
    return n;
}
/**返回一个整数,该整数等于((short)n)转换获得的short*/
公共静态int int2short(int n){
整数符号=n>0?1:-1;
int增量=符号*(Short.MAX\u值-Short.MIN\u值+1);
对于(;n>Short.MAX_值| | n
short
增加到其最大值之外称为溢出。发生溢出时,该值将成为该类型的最小值,并再次开始计数

下面是您如何通过尝试在
short
中存储0+123456得到-7616的:

0 --> 32767

-32768 --> 32767

-32768 --> -7616
换句话说,

32768+ 32768+ 32768+ (32768 -7616) = 123456

复合赋值运算符
+=
(它们都是真的)

形式为
E1 op=E2
的复合赋值表达式是等效的 to
E1=(T)((E1)op(E2))
,其中
T
E1
的类型,除了
E1
仅评估一次

所以

变成

s = (short) (s + x);
现在,由于
s
short
x
int
,因此
short
值被转换为
int
(这不是问题)

适用于

[…]可能会丢失有关 数值的总大小,也可能会失去精度和 射程

事情就是这样

s = -7608

好问题!它让我想到了一些我很久没想到的事情,我不得不温习一些概念。谢谢你帮我把脑子里的锈去掉

对我来说,这类问题最好以二进制形式呈现(原因很快就会变得显而易见):

您的原始数字(请原谅前导的零;我喜欢4人一组):

0001 1110 0010 0100 0000

然而,根据Java语言规范(JLS),short是一个16位带符号2的补码整数。将整数值123456分配给短路称为“缩小原语转换”,这将在中介绍。具体来说,“有符号整数到整数类型T的窄化转换只会丢弃除n个最低阶位以外的所有位,其中n是用于表示类型T的位数。”

丢弃除最低16位以外的所有位会给我们留下:

1110 0010 0100 0000

在无符号整数中,该值为57290,但短整数是有符号2的补码整数。最左边数字中的1表示负数;要获取数字的值,必须:

原件:

1110 0010 0100 0000

反转位:

0001 1101 1011 1111

加1:

0001 1101 1100 0000

将其转换为十进制并添加负号以获得-7616


再次感谢你提出这个问题。不知道也没关系,所以继续问下去,继续学习。我回答得很开心…我喜欢跳进JLS,疯狂,我知道

谢谢你的详细解释。我期待这样的答案,因为在不同的整数短值给出不同的值,这让我困惑!再次感谢@迪奇,因为事情就是这样做的。如果你想要更多的细节,而不是在评论中,我文章的最后一个链接解释了为什么倒数加1可以得到两个负数的补码。《论二》的补语对这一主题的处理更为严格。
s = (short) (8 + 123456)
s = (short) (123464)
s = -7608