传送门

传送门2

以下copy:

int i = 0;
  i += ((b[0] & 0xff) << 24);
  i += ((b[1] & 0xff) << 16);
  i += ((b[2] & 0xff) << 8);
  i += ((b[3] & 0xff));

想必大家对这样的代码并不陌生,明白就可以不看了,想了解的继续往下看,不好的地方还请多多包涵!
个人经常看到这样的写法但是不明白为何,所以忽然想了解下于是研究了下.

有一定的计算机2进制计算基础的就可以看明白,如果不明白2进制,先去看看计算机2进制计算及转换之类的东西

===========开始...

原码,反码,补码概念
+1原 = 0000 0001
-1原  = 1000 0001
反码
正数的反码是其本身
负数的反码是在其原码的基础上, 符号位不变,其余各个位取反.
补码
正数的补码就是其本身
负数的补码是在其原码的基础上, 符号位不变, 其余各位取反, 最后+1. (即在反码的基础上+1)

一部分int转byte
Java采用[补码]存储整数 int型为4字节 32位,byte为1字节8位
所以byte[]数组中存储一个int类型肯定是4个1字节的byte组成,即byte[4]才可以存放一个int值
就算int 是0在计算中也是占用个32位表示:00000000 00000000 00000000 00000000 存入byte中即4个下标中均为0
int直接存入byte数组中及原理:

int a =1246;
二进制表示
|------高16位----------|  |---------低16位-------|
00000000 00000000 00000100 11011110
|   A         | |   B        | |   C         | |   D         |
[0]              [1]             [2]              [3]   放入byte[]数组原理,将这个2进制以8位为1个字节存入byte数组中从数组下标0开始存入
最后byte[]数组存储为这样
[0]=00000000   补码后00000000转10进制真实数值0
[1]=00000000   补码后00000000转10进制真实数值0
[2]=00000100   补码后00000100转10进制真实数值4
[3]=11011110   补码后10100010转10进制真实数值-34,
                         最后8位11011110最高位是符合位,1负0正,补码规则: 符号位不变, 其余各位取反,
                         最后+1得到:10100010 0100010=34+负号"1"所以=-34
转换过程中进行&运算就是高位舍去,通俗就是不需要的数据清0处理,下面琢行说明:

由于byte只有8位,int32位,所以我们需要位移,把前面的每8位一组移动到最后8位上面来进行计算,其他数值都不参与计算
int a =1246;
byte[] b = new byte[4];
第一步:
b[0] = (byte) (a >> 24 & 0xff);
将00000000 00000000 00000100 11011110 A区域移动到D区域往右边推动24位,主要获取A取的值
00000000 00000000 00000100 11011110
                                                   00000000 00000000 00000100 11011110形成这样的
空白的数据被抹掉就是0表示,移动后超出了D区域数据属于溢出情况也舍掉最后形成如下
00000000 00000000 00000000 00000000
最后做&计算,这里移动了24位,右边的数据都被溢出了,做不做这个计算都没影响,还是表示下
00000000 00000000 00000000 00000000
00000000 00000000 00000000 11111111  &计算0xFF的2进制
-------------------------------------------------------
 00000000 00000000 00000000 00000000 结果还是0

第二步:
b[1] = (byte) ((a >> 16) & 0xff);
将00000000 00000000 00000100 11011110 B区域移动到D区域往右边推动16位,主要获取B取的值
00000000 00000000 00000100 11011110
                                  00000000 00000000 00000100 11011110形成这样的
空白的数据被抹掉就是0表示,移动后超出了D区域数据属于溢出情况也舍掉最后形成如下
00000000 00000000 00000000 00000000
00000000 00000000 00000000 11111111  &计算0xFF的2进制
---------------------------------------------------------
00000000 00000000 00000000 00000000 结果还是0

第三步:
b[2] = (byte) ((a >> 8) & 0xff);
将00000000 00000000 00000100 11011110 C区域移动到D区域往右边推动8位,主要获取C取的值
00000000 00000000 00000100 11011110
                 00000000 00000000 00000100 11011110形成这样的
空白的数据被抹掉就是0表示,移动后超出了D区域数据属于溢出情况也舍掉最后形成如下
00000000 00000000 00000000 00000100
00000000 00000000 00000000 11111111  &计算0xFF的2进制
-------------------------------------------------------
00000000 00000000 00000000 00000100补码后的2进制,上面的每一步最后都要参与补码,只是因为0就没写了
 转10进制最终结果是4

第四步:
b[3] = (byte) (a & 0xff);
将00000000 00000000 00000100 11011110 计算D区的值,由于D取直接就是在末尾8位上,所以不需要移动,
直接&计算,这里充分体现出来&0xFF计算就是清除其余不需要的数据,由于8位前还有0100 这么个数,
但是我们只需要后8位,所以&FF计算清除掉
00000000 00000000 00000100 11011110
00000000 00000000 00000000 11111111  &计算0xFF的2进制
-------------------------------------------------------
00000000 00000000 00000000 11011110结果
这个结果转10进制:222,可见是有问题的,int->byte我们只需要拿出最后8位出来进行处理11011110,
上面提过最高位(左边0的位置)是符号位:0表示正数,1表示负数
计算过程中只看后面7位1011110转10进制:94加上前面的符号得到-94,但这个数也不对
因为java采用补码存储整数
所以我们需要对1011110这个负数进行补码:负数的补码是在其原码的基础上, 符号位不变, 其余各位取反, 最后+1. (即在反码的基础上+1)
1011110
1100001再+1 1100001+1=1100010
最后1100010转10进制(只看后面7位100010):34前面加符号-34才是最终结果

二部分byte转int
对于一个单一的byte转int就是其本身,因为byte范围是-128--127如果输入超过这个数直接编译不通过
byte i=12;
int c=(int)i;
c=12;

像前面一部分,int转byte后得到的是一个4字节的byte[]数组,因为int长度就是4字节,不管值有多大或是0 byte[]也是4个长度,里面的值都是0;
继续上面的最终byte[]数组中的结果是
byte[] b ={0,0,4,-34};从下标0-4存的是int类型的高位到低位的顺序
|------高16位-----------| |---------低16位--------|
00000000 00000000 00000100 11011110
|   0         | |   0         | |   4         | |  -34        |
int 到byte是向右移动,那转换回来就是反其道而行之

第一步:
00000000 00000000 00000100 11011110原2进制
                                                   00000000 00000000 00000100 11011110原来下标0的数被移右动24位
所以获取下标[0]<<24左移24位
下标[0]=0转2进制
00000000 00000000 00000000 00000000  左移24位后的2进制,因为0怎么移动都是0
00000000 00000000 00000000 11111111  再进行&FF运算,为何要&FF后面比较直观,这里是0所以不讲解了
00000000 00000000 00000000 00000000  补码
-----------------------------------------
结果0

第二步:
00000000 00000000 00000100 11011110原2进制
                                  00000000 00000000 00000100 11011110原来下标1的数被移右动16位
所以获取下标[1]<<16左移16位,当然后面的2组数以不存在,移动后整个32位的2进制就是如下
下标[1]=0转2进制00000000
00000000 00000000 00000000 00000000  左移16位后的2进制,因为0怎么移动都是0
00000000 00000000 00000000 11111111  再进行&FF运算,为何要&FF后面比较直观,这里是0所以不讲解了
00000000 00000000 00000000 00000000  补码
-----------------------------------------
结果0

第三部分:
00000000 00000000 00000100 11011110原2进制
                 00000000 00000000 00000100 11011110原来下标2的数被移右动8位
所以获取下标[2]<<8左移8位,当然后面的1组数以不存在,移动后整个32位的2进制就是如下
下标[2]=4转2进制00000100
 00000000 00000000 00000100 00000000  左移8位后的2进制
&00000000 00000000 00000000 11111111  再进行&FF运算,为何要&FF后面比较直观,这里是0所以不讲解了
-----------------------------------------
 00000000 00000000 00000100 00000000
 00000000 00000000 00000100 00000000补码,正数补码是其本身
 结果100 00000000转10进制=1024

第四部分:
下标[3]=-34转2进制11111111 11111111 11111111 11011110
11111111 11111111 11111111 11011110原来下标3的数就是末尾8位没有发生过移动,所以不需要位移
00000000 00000000 00000000 11111111这里比较直观&FF计算去掉不需要的数据,可以称作清0操作
-----------------------------------------
00000000 00000000 00000000 11011110结果
00000000 00000000 00000000 11011110补码后
这时11011110并不是负数,因为现在是byte转int上面进行&FF运算后最高位是0,所以是正数,正数补码就是本身
-----------------------------------------
所以转10进制后=222
将最终的4个结果相加0+0+1024+222=1246

---------------------

本文来自 曦语 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/qq_31232515/article/details/75009161?utm_source=copy

byte -> int的更多相关文章

  1. java中byte, int的转换

    最近在做些与编解码相关的事情,又遇到了byte和int的转换,看着那些关于反码.补码的说明依旧头疼,还是记下些实用的方法吧.int -> byte可以直接使用强制类型转换: byte b = ( ...

  2. 【转】java中byte, int的转换, byte String转换

    原文网址:http://freewind886.blog.163.com/blog/static/661924642011810236100/ 最近在做些与编解码相关的事情,又遇到了byte和int的 ...

  3. byte + byte = int

    byte+byte=int,低级向高级是隐式类型转换,高级向低级必须强制类型转换,byte<char<short<int<long<float<double

  4. (转)教你完全理解IO流里的 read(),read(byte[]),read(byte[],int off,int len)以及write

    背景:对于IO部分,总是感觉很虚,不能很好的理解其中的要义,其实仔细分析,掌握其中的规律,一切都会看起来十分的自然. 1 理解 1.1 从头总结 长期以来,java中的InputStream Outp ...

  5. 【Go入门教程4】变量(var),常量(const),内置基础类型(Boolean、数值 byte,int,rune、字符串、错误类型),分组,iota枚举,array(数值),slice(切片),map(字典),make/new操作,零值

    这小节我们将要介绍如何定义变量.常量.Go 内置类型以及 Go 程序设计中的一些技巧. 定义变量 Go 语言里面定义变量有多种方式. 使用 var 关键字是 Go 最基本的定义变量方式,与 C 语言不 ...

  6. python3 byte,int,str转换

    1 # bytes 与 int 2 b=b'\x01\x02' 3 num=int.from_bytes(b,'little') 4 print('bytes转int:',num) 5 6 b1=nu ...

  7. C++: byte 和 int 的相互转化

    原文链接:http://blog.csdn.net/puttytree/article/details/7825709 NumberUtil.h // // NumberUtil.h // MinaC ...

  8. java音视频编解码问题:16/24/32位位音频byte[]转换为小端序short[],int[],以byte[]转short[]为例

    前言:Java默认采用大端序存储方式,实际编码的音频数据是小端序,如果处理单8bit的音频当然不需要做转换,但是如果是16bit或者以上的就需要处理成小端序字节顺序. 注:大.小端序指的是字节的存储顺 ...

  9. java中的int与byte的转化

    java中的int与byte的转化 1.基础准备 1.1.原码 就是二进制码,最高位为符号位,0表示正数,1表示负数,剩余部分表示真值 1.2.反码 在原码的基础上,正数反码就是他本身,负数除符号位之 ...

随机推荐

  1. [UE4]抓取准备

    一.引擎的VR实例工程是使用手柄进行抓取的.我们需要加上可以使用鼠标进行抓取操作. 二.将左右手保存到全局变量. 三.左右手分别调用抓取和扔方法

  2. SAS 统计某个数据集各个字段频数,并汇集到一个表中

    /*统计表的字段*/ PROC CONTENTS DATA=SASHELP.CLASS NOPRINT OUT=CA(KEEP=NAME); RUN; /*提取表的变量名*/ PROC SQL NOP ...

  3. Troubleshooting 10g and 11.1 Clusterware Reboots (文档 ID 265769.1)

    Troubleshooting 10g and 11.1 Clusterware Reboots (文档 ID 265769.1) This document is intended for DBA' ...

  4. 关于mysql文件导入提示“Variable @OLD_CHARACTER_SET_CLIENT can't be set to the value of @@CHARACTER_SET_CLIENT”问题分析

    今天用myssqldump导出数据,然后再导入另外mysql数据库时,提示Variable @OLD_CHARACTER_SET_CLIENT can't be set to the value of ...

  5. mysql集群搭建--韩国庆

    按照我给大家提供的步骤,一步一步来,你就能配好mysql集群环境 什么是mycat 简单的说,MyCAT就是: •一个彻底开源的,面向企业应用开发的“大数据库集群” •支持事务.ACID.可以替代My ...

  6. 关于js-xlsx的简单使用

    关于js-xlsx的简单使用 最近要做一个东西用到对excel的操作,就是在前端将excel加载进来,操作后再生成excel,在网上找了很多种办法,能够实现的demo是下面这个: 纯前端利用 js-x ...

  7. Hexo:创建属于你自己的博客

    step: 1.install node.js,git,github 2.npm install -g hexo-cli 3.mkdir hexo 4.cd hexo mkdir blog 5.cd ...

  8. html--form表单

    <!-- form 标签 作用:收集并提交用户的信息 属性: id   表单的id,用于js获取表单 name 表单的名字,用于js获取表单 action 表单提交的地址 method 表单提交 ...

  9. jQuery入门基础(选择器)

    一.jQuery简介 jQuery 是一个 JavaScript 库. jQuery 极大地简化了 JavaScript 编程. jQuery 库位于一个 JavaScript 文件中,其中包含了所有 ...

  10. 魔力Python--经典SQL语法大全

    具体转载自哪里,我也忘记了... 一.基础 1.说明:创建数据库 CREATE DATABASE database-name 2.说明:删除数据库 drop database dbname 3.说明: ...