Java中的byte详解
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详解相关推荐
- Java中JDBC连接数据库详解
今天动力节点java学院小编分享的是JDBC连接数据库的相关知识,希望通过看过此文,各位小伙伴对DBC连接数据库有所了解,下面就跟随小编一起来看看JDBC连接数据库的知识吧. 一.JDBC连接数据库概 ...
- JAVA中的Random详解
JAVA中的Random详解 首先,在JDK自带的常用的random中有两个,这俩都是产生随机数的,不过一个是util下的random,另外一个是Math下的.我们分别介绍一下 util中的rando ...
- java中new关键字详解
java中new关键字详解 在java中我们可以经常使用new来创建一个对象,但是这对于初学者来说可能只会使用却不能理解new关键字和它的语法 new关键字的语法 注意使用前先导包,一般我们使用ide ...
- Java中super关键字详解
Java中super关键字详解 super有什么用? super什么时候不可以省略呢? super在内存图中是如何存在的呢? super使用时的注意事项 super有什么用? (1)当子类中构造方法第 ...
- Java中Iterator迭代器详解
目录 一.Java中Iterator迭代器详解 1.为什么需要迭代器 2.迭代器长什么样子 3.如何使用迭代器 使用步骤: 代码演示: 迭代器可以简化为增强型for循环: 4.Iterator与Lis ...
- Java 中IO流详解(附实例代码/面试题)
Java I/O流详解 前言 一.I/O流是什么? 二.IO流分类: 1. 流程图: io流对象 2. io流的优缺点: 3. io 流Java中用途有哪些? 三.一些 io 实例 四.面试题: 前言 ...
- java中IO流详解
不断更新中!!! 1.流的定义及分类 流是个抽象的概念,是对输入输出设备的抽象,Java程序中,对于数据的输入/输操作都是以"流"的方式进行.设备可以是文件,网络,内存等.将数据从 ...
- Java中的Base64详解
详解Java中的Base64原理跟用法 简介 Base64编码,是我们程序开发中经常使用到的编码方法.它是一种基于用64个可打印字符来表示二进制数据的表示方法.它通常用作存储.传输一些二进制数据编 ...
- java中的IO详解(下)
BufferedReader的小例子 注意: BufferedReader只能接受字符流的缓冲区,因为每一个中文需要占据两个字节,所以需要将System.in这个字节输入流变为字符输入流,采用: 1 ...
最新文章
- 屏蔽敏感词的正则表达式
- 数据恢复工具PhotoRec
- 奇奇怪怪的大佬:理发店小弟到阿里P10
- linux系统启动过程(三)
- python sort 多级排序_为什么在python中使用排序功能进行多级排序...
- Bootstrap3轮番插件的选项
- 素数和 mooc 翁恺
- 【深度学习】深度学习门前徘徊——正向传播
- Dll中的方法向外返回dynamic类型可能会失败
- hadoop工作流引擎azkaban
- log4j的详细介绍
- 香农编码、哈夫曼编码、费诺编码的特点、优缺点及应用
- 《引爆点》学习笔记二
- 《Constrained Convolutional Neural Networks for Weakly Supervised Segmentation》翻译
- 如何用html写抖动效果,利用transition实现文字上下抖动的效果
- Celltrion发布抗COVID-19单克隆抗体治疗瑞丹维单抗(CT-P59)全球III期试验的阳性顶线结果
- 【随笔记】我与Java的故事
- LinuxC——指针
- sublime 使用浏览器不反应
- 第六课:ResNeXt学习
热门文章
- Flex 布局教程——阮老师
- matlab scope 怎么调出,matlab怎么设置scope
- 深圳华强北日系元件每日一价 最高单品涨幅150%
- git diff的生成方式:myers diff算法
- java字典初始化_字典翻译注解讲解
- XDOJ最小周期串 297
- electron打包后启动应用,提示cannot find module fs/promises的解决
- 【Kevin Learn 小程序】-->picker
- 【catkin】——将自己代码打包成catkin包
- 安装Oracle 11g时遇到“【INS-13001】此环境不满足最低配置”的问题解决