Java中的byte详解

介绍

byte,即字节,由8位的二进制组成。在Java中,byte类型的数据是8位带符号的二进制数。

在计算机中,8位带符号二进制数的取值范围是[-128, 127],所以在Java中,byte类型的取值范围也是[-128, 127]。

byte取值范围分析

一直在想为什么不是 -128 到 128呢?今天分析了一下这个问题。

首先我们得明白一件事情,那就是运算规则(因为计算机中的数是以反码形式存储的,反码再求反码得到该数真值):

正数的最高位都是 0 ,正数的值就是二进制表示的值。

负数的最高位都是 1 ,负数的值是 取反后加一 然后加个负号得到得值。

我们用8位的二进制来说明一下此规则:

比如:00000001。最高位是0 为正数 ,那么表示的就是 十进制的 1。

再比如:10000001.最高位是1 为负数,值是多少?取反得到 01111110 加1 得到 01111111 ,那么值为 -127 (可能你会有疑问了?why?-127不是应该是1111 1111,先不急,可以去看下面要说的 反码,你就懂了)

理解此运算规则我们正式开始说byte,byte正好是8位的二进制数。short是16位 int是32位 long是64位。

不难理解,byte的最大正数就是 01111111(最高位必须是0),也就是 127。

那么你可能会想 byte的最小负数就是 11111111 了,对不对? 这么想就

大错特错了。让我们看看11111111这个二进制数表示多少。

根据上面的提示 我们知道这是一个负数。它的值是先取反再加1 。

11111111取反得到:00000000,加1得到 00000001 。最后得到的值为-1.

这可是最大的负数啊。由此你是不是想到了最小的负数会不会是10000000呢?

让我们算一下 取反:01111111 加1得到 10000000 最后得到 -128.

127是01111111 然而 -128是10000000 ,看出来一个奇怪的事情。

仔细的看一下这两个二进制数 是不是前者加1就得到后者呢?对。

可以编一个小程序实验一下:

byte a = 127;
a+=1;
System.out.println(a);

结果正好是-128

由此我们可以看出来二进制从 00000000 到01111111到10000000到 11111111

即 十进制从 0 到 127 到 -128 到 -1。

接下来,我们用一段代码来更深刻地理解byte:

public class A {public static void main(String[] args) {int b = 456;byte test = (byte) b;System.out.println(test);}
}

上述代码,最后会输出-56。原因如下:

456的二进制表示是111001000,由于int是32位的二进制,所以在计算机中,实际上是00000000000……111001000,当int转成byte的时候,那么计算机会只保留最后8位,即11001000

然后11001000的最高位是1,那么表示是一个负数,而负数在计算机中都是以补码的形式保存的,所以我们计算11001000的原码为00111000,即56,所以11001000表示的是-56,所以最后test的值为-56。

byte\short\int\long

java中存储的数据类型均带符号,即看最高位:为0表示正数,为1表示负数

类型 字节数 bit位数 取值范围
byte 1 8 -128到127
short 2 16 -215到215-1
int 4 32 -231到231-1
long 8 64 -263到263-1

原码\反码\补码

原码:就是二进制码,最高位为符号位,0表示正数,1表示负数,剩余部分表示真值。

反码:在原码的基础上,正数反码就是他本身,负数除符号位之外全部按位取 反。

补码:正数的补码就是自己本身, 负数的补码是在自身反码的基础上加1.

逻辑运算符

包含: &(与), | (或), ^ (异或),~ (按位取反)

& :当2个都为1的时候为1, 其他都是0 。 1&1 = 1, 1&0 = 0, 0&0 = 0; 他的作用是清0

| : 当2个只要有一个为1,就是1. 1|0 = 1; 0|0 = 0, 1|1 = 1;

^: 相同为0, 不相同为1, 1^0 = 1, 1^1 = 0, 0^0 = 0; 他的作用是定位翻转。

~: 按位取反,0变为1, 1变为0;

之所以要明确原码,反码,补码,是因为java中变量都是以补码的形式保存的。

比如 整行30 他的原码是:0001 1110. 正数,所以反码,补码都是0001 1110.

对于负数:-7 ,他的原码是 1000 0111, 第一位1表示是此数是负数。他的反码是:1111 1000, 补码在反码的基础上加1, 所以它的补码是1111 1001, 所以他的二进制数就是1111 1001.

如“-16+11”的运算:

11110000     + -16的补码
00001011       11的补码
————
11111011       - 5的补码

移位操作符

包含:<<, >>, >>>

<< 表示左移,不分正负数,丢去高位,低位补0,如果移动的位数大于32, 那么就需要取余(例如下方<<10等价于<<2)

注:以下数据类型默认为byte-8位

左移时不管正负,低位补0

正数:r = 20 << 2

20的二进制补码:0001 0100

向左移动两位后:0101 0000

结果:r = 80

负数:r = -20 << 2

-20 的二进制原码 :1001 0100

-20 的二进制反码 ***:*1110 1011

-20 的二进制补码 :1110 1100

左移两位后的补码:1011 0000

反码:1010 1111

原码:1101 0000

结果:r = -80

>>表示右移,如果该数为正,则高位补0,若为负数,则高位补1

注:以下数据类型默认为byte-8位

正数:r = 20 >> 2

20的二进制补码:0001 0100

向右移动两位后:0000 0101

结果:r = 5

负数:r = -20 >> 2

-20 的二进制原码 :1001 0100

-20 的二进制反码 :1110 1011

-20 的二进制补码 :1110 1100

右移两位后的补码:1111 1011

反码:1111 1010

原码:1000 0101

结果:r = -5

>>>表示无符号右移,也叫逻辑右移,即若该数为正,则高位补0,而若该数为负数,则右移后高位同样补0

正数: r = 20 >>> 2

的结果与 r = 20 >> 2 相同;

负数: r = -20 >>> 2

注:以下数据类型默认为int 32位

-20:源码:10000000 00000000 00000000 00010100

反码:11111111 11111111 11111111 11101011

补码:11111111 11111111 11111111 11101100

右移:00111111 11111111 11111111 11111011

结果:r = 1073741819

大小端模式

大端模式,是指数据的高字节保存在内存的低地址中,而数据的低字节保存在内存的高地址中,这样的存储模式有点儿类似于把数据当作字符串顺序处理:地址由小向大增加,而数据从高位往低位放;这和我们的阅读习惯一致。

小端模式,是指数据的高字节保存在内存的高地址中,而数据的低字节保存在内存的低地址中,这种存储模式将地址的高低和数据位权有效地结合起来,高地址部分权值高,低地址部分权值低。

下面以unsigned int value = 0x12345678为例,分别看看在两种字节序下其存储情况,我们可以用unsigned char buf[4]来表示value

Big-Endian: 低地址存放高位,如下:
高地址

​ buf[3] (0x78) – 低位
​ buf[2] (0x56)
​ buf[1] (0x34)
​ buf[0] (0x12) – 高位

​ 低地址
Little-Endian: 低地址存放低位,如下:
​ 高地址

​ buf[3] (0x12) – 高位
  buf[2] (0x34)
  buf[1] (0x56)
  buf[0] (0x78) – 低位

​ 低地址

内存地址 小端模式存放内容 大端模式存放内容
0x4000 0x78 0x12
0x4001 0x56 0x34
0x4002 0x34 0x56
0x4003 0x12 0x78

int与byte[]相互转换

  /*** int到byte[] 由高位到低位* @param i 需要转换为byte数组的整行值。* @return byte数组*/public static byte[] intToByteArray(int i) {byte[] result = new byte[4];result[0] = (byte)((i >> 24) & 0xFF);result[1] = (byte)((i >> 16) & 0xFF);result[2] = (byte)((i >> 8) & 0xFF);result[3] = (byte)(i & 0xFF);return result;}/*** byte[]转int* @param bytes 需要转换成int的数组* @return int值*/public static int byteArrayToInt(byte[] bytes) {int value=0;for(int i = 0; i < 4; i++) {int shift= (3-i) * 8;value +=(bytes[i] & 0xFF) << shift;}return value;}

注意事项

c语言中数据类型分为有符号数和无符号数,但是在java中只有有符号数,不存在无符号数.所以当我们与硬件人员共同开发项目时,解析协议里面的byte[]要注意跟硬件人员确定是否带符号.带符号就跟java中一样处理即可.不带符号的话就要小心了,如果还按照java常规方法解析可能会越界.所以一般我们在byte[]转int值时,当作byte[]转long处理即可;在int转byte[]时,当作long转byte[],然后截取后4个字节(大端模式转换)

Java中的byte详解相关推荐

  1. Java中JDBC连接数据库详解

    今天动力节点java学院小编分享的是JDBC连接数据库的相关知识,希望通过看过此文,各位小伙伴对DBC连接数据库有所了解,下面就跟随小编一起来看看JDBC连接数据库的知识吧. 一.JDBC连接数据库概 ...

  2. JAVA中的Random详解

    JAVA中的Random详解 首先,在JDK自带的常用的random中有两个,这俩都是产生随机数的,不过一个是util下的random,另外一个是Math下的.我们分别介绍一下 util中的rando ...

  3. java中new关键字详解

    java中new关键字详解 在java中我们可以经常使用new来创建一个对象,但是这对于初学者来说可能只会使用却不能理解new关键字和它的语法 new关键字的语法 注意使用前先导包,一般我们使用ide ...

  4. Java中super关键字详解

    Java中super关键字详解 super有什么用? super什么时候不可以省略呢? super在内存图中是如何存在的呢? super使用时的注意事项 super有什么用? (1)当子类中构造方法第 ...

  5. Java中Iterator迭代器详解

    目录 一.Java中Iterator迭代器详解 1.为什么需要迭代器 2.迭代器长什么样子 3.如何使用迭代器 使用步骤: 代码演示: 迭代器可以简化为增强型for循环: 4.Iterator与Lis ...

  6. Java 中IO流详解(附实例代码/面试题)

    Java I/O流详解 前言 一.I/O流是什么? 二.IO流分类: 1. 流程图: io流对象 2. io流的优缺点: 3. io 流Java中用途有哪些? 三.一些 io 实例 四.面试题: 前言 ...

  7. java中IO流详解

    不断更新中!!! 1.流的定义及分类 流是个抽象的概念,是对输入输出设备的抽象,Java程序中,对于数据的输入/输操作都是以"流"的方式进行.设备可以是文件,网络,内存等.将数据从 ...

  8. Java中的Base64详解

    详解Java中的Base64原理跟用法 简介 ​ Base64编码,是我们程序开发中经常使用到的编码方法.它是一种基于用64个可打印字符来表示二进制数据的表示方法.它通常用作存储.传输一些二进制数据编 ...

  9. java中的IO详解(下)

    BufferedReader的小例子 注意: BufferedReader只能接受字符流的缓冲区,因为每一个中文需要占据两个字节,所以需要将System.in这个字节输入流变为字符输入流,采用: 1  ...

最新文章

  1. 屏蔽敏感词的正则表达式
  2. 数据恢复工具PhotoRec
  3. 奇奇怪怪的大佬:理发店小弟到阿里P10
  4. linux系统启动过程(三)
  5. python sort 多级排序_为什么在python中使用排序功能进行多级排序...
  6. Bootstrap3轮番插件的选项
  7. 素数和 mooc 翁恺
  8. 【深度学习】深度学习门前徘徊——正向传播
  9. Dll中的方法向外返回dynamic类型可能会失败
  10. hadoop工作流引擎azkaban
  11. log4j的详细介绍
  12. 香农编码、哈夫曼编码、费诺编码的特点、优缺点及应用
  13. 《引爆点》学习笔记二
  14. 《Constrained Convolutional Neural Networks for Weakly Supervised Segmentation》翻译
  15. 如何用html写抖动效果,利用transition实现文字上下抖动的效果
  16. Celltrion发布抗COVID-19单克隆抗体治疗瑞丹维单抗(CT-P59)全球III期试验的阳性顶线结果
  17. 【随笔记】我与Java的故事
  18. LinuxC——指针
  19. sublime 使用浏览器不反应
  20. 第六课:ResNeXt学习

热门文章

  1. Flex 布局教程——阮老师
  2. matlab scope 怎么调出,matlab怎么设置scope
  3. 深圳华强北日系元件每日一价 最高单品涨幅150%
  4. git diff的生成方式:myers diff算法
  5. java字典初始化_字典翻译注解讲解
  6. XDOJ最小周期串 297
  7. electron打包后启动应用,提示cannot find module fs/promises的解决
  8. 【Kevin Learn 小程序】-->picker
  9. 【catkin】——将自己代码打包成catkin包
  10. 安装Oracle 11g时遇到“【INS-13001】此环境不满足最低配置”的问题解决