精华内容
下载资源
问答
  • Java四种基本整数数据类型最近在学习位运算符时,发现负数在做带符号位的右移运算符时,结果与想象中的大不一样,经过查阅资料之后发现,原来这一切源自负数在计算机中的储存方式 负数在计算机中是以补码的形式储存...

    65e37490edfad6f87cc5e74ffa48fd8e.png

    0fdac3d4aee5d853981c5e135fb787c8.png
    Java四种基本整数数据类型

    最近在学习位运算符时,发现负数在做带符号位的右移运算符时,结果与想象中的大不一样,经过查阅资料之后发现,原来这一切源自负数在计算机中的储存方式
    负数在计算机中是以补码的形式储存的注意: 本文为了简化运算,二进制数都是用一个字节——8个二进制位说明
    1 一些概念
    在进行问题探究之前,先了解一些概念
    1.1 原码
    原码就是符号位加上真值的绝对值,即8位二进制数的第一位是符号位,其余位表示值
    +1(原) = 0000 0001
    -1(原) = 1000 0001
    第一位表示正负号,所以8位二进制数的取值范围是
    [1111 1111 , 0111 1111]
    即[-127,127]
    1.2 反码
    正负数的反码规则不一样
    正数的反码就是其本身
    负数的反码就是,在原码的基础上,符号位不变,其余位取反
    +1 = [0000 0001]原 = [0000 0001]反
    -1 = [1000 0001]原 = [1111 1110]反
    1.3 补码
    补码的计算规则为
    正数的补码就是其本身
    负数的补码就是在其反码的基础上+1
    +1 = [0000 0001]原 = [0000 0001]反 = [0000 0001]补
    -1 = [1000 0001]原 = [1111 1110]反 = [1111 1111]补
    2 为何这么复杂
    从上面我们可以知道,负数的原码、反码、补码是很不一样的,这样设计的好处是方便计算机做减法
    首先,因为人可以轻松知道第一位是符号位,在计算的时候我们会根据符号位,选择对真值区域的加减。但是要让计算机辨别"符号位"显然会让计算机的基础电路设计变得十分复杂!于是就想出了将符号位也参与运算的方法。我们知道,根据运算法则减去一个正数等于加上一个负数,即:1 - 1 = 1 + (-1) = 0 ,所以机器可以只有加法而没有减法,这样计算机运算的设计就更简单了
    于是开始探索将符号位参与运算,并且只保留加法的方法
    以1-1=0为例原码
    1 - 1 = 1 + (-1) =
    [0000 0001]原
    + [1000 0001]原
    ---------------------
    = [1000 0010]原
    = -2
    如果用原码表示,让符号位也参与计算,显然对于减法来说,结果是不正确的。这也就是为何计算机内部不使用原码表示一个数反码
    1 - 1 = 1 + (-1) =
    [0000 0001]原
    + [1000 0001]原 =
    ------------------------
    [0000 0001]反
    + [1111 1110]反
    ------------------------
    = [1111 1111]反
    ------------------------
    = [1000 0000]原
    = -0
    发现用反码计算减法,结果的真值部分是正确的。而唯一的问题其实就出现在"0"这个特殊的数值上,虽然人们理解上+0和-0是一样的,但是0带符号是没有任何意义的。而且会有[0000 0000]原和[1000 0000]原两个编码表示0补码
    1-1 = 1 + (-1) =
    [0000 0001]原
    + [1000 0001]原 =
    ------------------------
    [0000 0001]补
    + [1111 1111]补
    ------------------------
    = [1 0000 0000]补(出现了一个9位二进制数,所以去除一位,变成)
    ------------------------
    = [0000 0000]补
    ------------------------
    = [0000 0000]原
    = 0
    这样0用[0000 0000]表示,而以前出现问题的-0则不存在了。而且可以用[1000 0000]表示-128
    再看看-1-127
    (-1) + (-127) =
    [1000 0001]原
    + [1111 1111]原 =
    ------------------------
    [1111 1111]补
    + [1000 0001]补
    ------------------------
    = [1 1000 0000]补(出现了一个9位二进制数,所以去除一位,变成)
    = [1000 0000]补
    -1-127的结果应该是-128,在用补码运算的结果中,[1000 0000]补 就是-128。但是注意因为实际上是使用以前的-0的补码来表示-128,所以-128并没有原码和反码表示。(对-128的补码表示[1000 0000]补算出来的原码是[0000 0000]原,这是不正确的)
    使用补码,不仅仅修复了0的符号以及存在两个编码的问题,而且还能够多表示一个最低数。这就是为什么8位二进制,使用原码或反码表示的范围为[-127, +127],而使用补码表示的范围为[-128, 127]
    从上述说明中,我们可以得知,通过使用补码,可以将减法变成加法,更符合计算机的运行规则
    3 补码的本质
    接下来看看负数补码的本质
    以-8为例,-8其实就是0-8
    [0000 0000]
    - [0000 1000]
    ------------------
    因为被减数([0000 0000])小于减数([0000 1000]),所以需要向上接一位,被减数就变成了[1 0000 0000],上面的式子也就成了
    [1 0000 0000]
    - [0000 1000]
    ------------------
    [1111 1000]
    其实上面的[1 0000 0000] = [1111 1111] + [0000 0001],所以上面的式子可以分解成
    [1111 1111]
    - [0000 1000]
    ------------------
    [1111 0111]
    + [0000 0001]
    ------------------
    [1111 1000]
    补码的两个步骤就是这么来的

    展开全文
  • Java int 类型过大变成负数

    千次阅读 2018-11-27 19:40:26
    int类型的数字,如果太大的话,这个正数,就会变成负数。 然后Java代码测试一下。 然后就如上测试那般,这个1一直+++++,到最后真的就变成负数啦。...

    int类型的数字,如果太大的话,这个正数,就会变成负数。

    大师兄

    然后Java代码测试一下。

    大师兄

    然后就如上测试那般,这个1一直+++++,到最后真的就变成负数啦。

    展开全文
  • 计算机存储系统使用补码标识,int类型占32位,首位是符号位:0表示正数,1表示负数正数补码与原码相同负数补码除符号位其余各位与原码取反,然后加1最近工作看到一个之前的人写的日期工具类,本来想用Apache的...

    计算机存储系统使用补码标识,int类型占32位,首位是符号位:0表示正数,1表示负数。

    正数补码与原码相同

    负数补码除符号位其余各位与原码取反,然后加1

    最近工作看到一个之前的人写的日期工具类,本来想用Apache的commons包的DateUtils工具类,但是没有找到想要的方法,转而求其次使用封装的工具类,结果遇到一个问题。

    需求:给定一个Date对象,找到特定天数后的日期时间

    工具类的方法代码是这样写的:

    public static Date datetimeAddDay(Date datetime, int day) {

    datetime.setTime(datetime.getTime() + day * 24 * 60 * 60 * 1000);

    return datetime;

    }

    猛的一看,并没有什么不对,结果运行时日期不对,写个测试类跑了一下,大吃一惊!!!

    @Test

    public void testDatetimeAddDay() {

    Date datetime = new Date();

    System.out.println("当前时间:" + datetime);

    Date datetimeAddDay = DateUtil.datetimeAddDay(datetime, 30);

    System.out.println("30天后:" + datetimeAddDay);

    }

    运行结果:

    9e81dd6ca1cf1afda3f7db359963bf43.png

    这时间还给我倒回去了,原来是工具类的方法加的毫秒数超过int类型最大值了 2的31次方-1,符号位成了1,整体变为负数。所以工具类中运算的毫秒数使用long类型即可!!!

    展开全文
  • 由于通讯协议中长度使用byte字节来表示,但在java中长度超过127的时候会变成负数,所以需要保证得到的长度是正数byte b& 0xFFhttp://www.blogjava.net/orangelizq/archive/2008/07/20/216228.html在剖析该问题前...

    由于通讯协议中长度使用byte字节来表示,但在java中长度超过127的时候会变成负数,所以需要保证得到的长度是正数byte b & 0xFF

    http://www.blogjava.net/orangelizq/archive/2008/07/20/216228.html

    在剖析该问题前请看如下代码

    public static String bytes2HexString(byte[] b) {

    String ret = "";

    for (int i = 0; i < b.length; i++) {

    String hex = Integer.toHexString(b[ i ] & 0xFF);

    if (hex.length() == 1) {

    hex = '0' + hex;

    }

    ret += hex.toUpperCase();

    }

    return ret;

    }

    上面是将byte[]转化十六进制的字符串,注意这里b[ i ] & 0xFF将一个byte和 0xFF进行了与运算,然后使用Integer.toHexString取得了十六进制字符串,可以看出

    b[ i ] & 0xFF运算后得出的仍然是个int,那么为何要和 0xFF进行与运算呢?直接 Integer.toHexString(b[ i ]);,将byte强转为int不行吗?答案是不行的.

    其原因在于:

    1.byte的大小为8bits而int的大小为32bits

    2.java的二进制采用的是补码形式

    ==================以下文字貌似有问题===================

    在这里先温习下计算机基础理论

    byte是一个字节保存的,有8个位,即8个0、1。

    8位的第一个位是符号位,

    也就是说0000 0001代表的是数字1

    1000 0000代表的就是-1

    所以正数最大位0111 1111,也就是数字127

    负数最大为1111 1111,也就是数字-128

    上面说的是二进制原码,但是在java中采用的是补码的形式,下面介绍下什么是补码

    1、反码:

    一个数如果是正,则它的反码与原码相同;

    一个数如果是负,则符号位为1,其余各位是对原码取反;

    2、补码:利用溢出,我们可以将减法变成加法

    对于十进制数,从9得到5可用减法:

    9-4=5    因为4+6=10,我们可以将6作为4的补数

    改写为加法:

    9+6=15(去掉高位1,也就是减10)得到5.

    对于十六进制数,从c到5可用减法:

    c-7=5    因为7+9=16 将9作为7的补数

    改写为加法:

    c+9=15(去掉高位1,也就是减16)得到5.

    在计算机中,如果我们用1个字节表示一个数,一个字节有8位,超过8位就进1,在内存中情况为(100000000),进位1被丢弃。

    ⑴一个数为正,则它的原码、反码、补码相同

    ⑵一个数为负,刚符号位为1,其余各位是对原码取反,然后整个数加1

    - 1的原码为                10000001

    - 1的反码为                11111110

    + 1

    - 1的补码为                11111111

    0的原码为                 00000000

    0的反码为                 11111111(正零和负零的反码相同)

    +1

    0的补码为               100000000(舍掉打头的1,正零和负零的补码相同)

    Integer.toHexString的参数是int,如果不进行&0xff,那么当一个byte会转换成int时,由于int是32位,而byte只有8位这时会进行补位,

    例如补码11111111的十进制数为-1转换为int时变为11111111111111111111111111111111好多1啊,呵呵!即0xffffffff但是这个数是不对的,这种补位就会造成误差。

    和0xff相与后,高24比特就会被清0了,结果就对了。

    ----

    Java中的一个byte,其范围是-128~127的,而Integer.toHexString的参数本来是int,如果不进行&0xff,那么当一个byte会转换成int时,对于负数,会做位扩展,举例来说,一个byte的-1(即0xff),会被转换成int的-1(即0xffffffff),那么转化出的结果就不是我们想要的了。

    而0xff默认是整形,所以,一个byte跟0xff相与会先将那个byte转化成整形运算,这样,结果中的高的24个比特就总会被清0,于是结果总是我们想要的。

    展开全文
  • 由于通讯协议中长度使用byte字节来表示,但在java中长度超过127的时候会变成负数,所以需要保证得到的长度是正数byte b& 0xFFhttp://www.blogjava.net/orangelizq/archive/2008/07/20/216228.html在剖析该问题前...
  • java byte 字节负数

    万次阅读 2015-12-09 16:05:09
    由于通讯协议中长度使用byte字节来表示,但在java中长度超过127的时候会变成负数,所以需要保证得到的长度是正数byte b & 0xFF http://www.blogjava.net/orangelizq/archive/2008/07/20/216228.html 在...
  • 问题来了为什么int 类型最大值+1后会变成负数? 这是因为整数在内存中使用的是补码的形式表示,最高位是符号位,0表示正数,1表示负数: 例如一个8位的整数 正数的补码:为这个数的2进制码,例如3:0000 0101 负数的...
  • java中使用补码处理数字,而且byte(8)的数字在扩展成int(32)类型的时候,正数填充0,负数填充1;2.负数的转变过程,正数的原码,反码,补码,都一样; 解决步骤:1. -5(5)在byte类型中的表示是1000 0011(0000 0011)...
  • java中使用补码处理数字,而且byte(8)的数字在扩展成int(32)类型的时候,正数填充0,负数填充1;2.负数的转变过程,正数的原码,反码,补码,都一样;解决步骤:1. -5(5)在byte类型中的表示是1000 0011(0000 0011) ...
  • 作为一个java开发人员,接触的基本都是上层的,都是以应用为主,根据业务实现功能,但今天无意间发现了一个小问题,int类型的129转成byte类型变成了-127,我知道是因为位数截取的原因,但是还没有探究过为什么是-127...
  • 作为一个java开发人员,接触的基本都是上层的,都是以应用为主,根据业务实现功能,但今天无意间发现了一个小问题,int类型的129转成byte类型变成了-127,我知道是因为位数截取的原因,但是还没有探究过为什么是-127...
  • java用补码表示负数

    千次阅读 2013-11-12 12:25:45
    他们既能表示正数,又能表示负数Java用2的补码(two's complement)这种编码来表示负数。2的补码是把一个值的所有位取反(即将1变成0,将0变成1),然后对其结果加1。例如,-42就是通过取反42中所有的位00101010来...
  • 1:先将负数中的负号去掉变成正数,使用二进制表示这个正数 2:将这个二进制正数所有的位取反,再加1,结到的二进制序列就是这个负数的补码 比如:-1,取其正值1,32位二进制表示为:...
  • 1.问答题“\hello”是正确的字符串常量吗?“你好KU”.length()和”\n\t\t”.length()的值分别是...“Bird”.compareTo(“Bird fly”)的值是正数还是负数?“I love this game”.contains(“love”)的值是true吗?...
  • java.time包中的Duration Class的plusDays(long)方法用于获取此持续时间的不可变副本,并添加指定的天数作为参数传递。...它可以是正数负数,但不能为null。返回值:此方法返回一个Duration,它是现有持续时间的...
  • JAVA memo2018

    2019-09-26 12:35:46
    2018/09/29正数变成对应的负数 2の補数(Two'scomplement) Math.abs() 絶対値 如何用一个函数就能实现将正数变成对应的负数,将负数变成对应的正数: int turn(int a) { a = ~a + 1; return a; ...
  • Java位运算

    2019-03-31 21:05:08
    正数右移,高位用0补,负数右移,高位用1补,当负数使用无符号右移时,用0进行部位(自然而然的,就由负数变成正数了) 注意:笔者在这里说的是右移,高位补位的情况。正数或者负数左移,低位都是用0补。(自行测试)...
  • System.out.println(3/2) 按整型计算 得11) >...=,这两个Java运算符对于负数不一样正数:右移n位等于除以2的n次方负数变成正数。3) && 短路与,前面为假,表达式为假,后面的操作不会进...
  • Java运算符

    2019-08-14 09:40:25
    System.out.println(3/2) 按整型计算 得1 1) >>= 前面是零补零,前面是一补一; 2) >>>= 无符号右移(强制右移都会移进一), ...负数变成正数。 3) && 短路与,前面为假,表达...
  • java取反逻辑

    千次阅读 2016-10-25 11:00:23
    java取反分两种情况:正数取反和负数取反 第一 正数取反 1 正数求补--等于其自身 2 第1步中补码的每位取反=b 3 第2步中的b的补码=此时符号位为1(最高位),保持不变,其余位取反(1变成0,0变成1) 4 第3步中...
  • 本文为大家解析了java原码补码反码的关系,供大家参考,具体内容如下原码:不管源数据是十进制还是十六进制,统统将数字转成二进制形式反码:把原码的二进制统统反过来,0变成1,1变成0补码:负数的反码加1,就是...
  • 1. 无符号右移 >...对于一个正数,无符号右移不会变成负数(相当于除以1再取整);但是对于一个负数,无符号右移会将负数变成正数;int i = -4;System.out.printf("%-10d %32s\n", i, Integer.t...
  • 本文为大家解析了java原码补码反码的关系,供大家参考,具体内容如下原码:不管源数据是十进制还是十六进制,统统将数字转成二进制形式反码:把原码的二进制统统反过来,0变成1,1变成0补码:负数的反码加1,就是...
  • 1. 无符号右移 >...对于一个正数,无符号右移不会变成负数(相当于除以1再取整);但是对于一个负数,无符号右移会将负数变成正数;int i = -4;System.out.printf("%-10d %32s\n", i, Integer.t...
  • 本文为大家解析了java原码补码反码的关系,供大家参考,具体内容如下原码:不管源数据是十进制还是十六进制,统统将数字转成二进制形式反码:把原码的二进制统统反过来,0变成1,1变成0补码:负数的反码加1,就是...
  • 本文为大家解析了java原码补码反码的关系,供大家参考,具体内容如下原码:不管源数据是十进制还是十六进制,统统将数字转成二进制形式反码:把原码的二进制统统反过来,0变成1,1变成0补码:负数的反码加1,就是...
  • java中输出~6=-7的原因

    2020-07-28 00:17:44
    重要的事情说在前边 ...负数的原码:是该数值的正值的符号位变成1 负数的反码:是其原码(除符号位)按位取反 负数的补码转换为原码:和原码变补码一样,除符号位外取反+1 负数补码:负数的反码+1 正/负数取反方
  • java >>和>>>区别

    2019-03-12 16:05:07
    对于负数而言,反码就是原码中所有1变成0,0变成1,补码就是在反码的基础上加1所得。 然后: &gt;&gt;:带符号右移,正数右移高位补0,负数右移高位补1; &gt;&gt;&gt;:无符号右移,不管是正数...
  • java移位运算

    2012-11-07 22:21:22
    首先java中整数int都是4个字节...可能正数移动后变成负数 >> 右移运算 a>>b 把a的二进制往右移动b个单位,如果a是正数,则高位空出来的空间用0填充,如果a是负数,则高位空出来的空间用1填充。 所以>>不会改变符号,
  • Java基础语法

    2020-08-03 17:48:12
    原码:用二进制表示数值的大小(第一位为符号位,0表示正数,1表示负数) 反码:由原码取反得到(1变成0,0变成1,符号位不变,计算原码到补码的中间过程) 补码:按(原码)位取反,末尾加1(计算机用补码进行计算...

空空如也

空空如也

1 2 3 4 5
收藏数 83
精华内容 33
关键字:

java正数变成负数

java 订阅