二进制知识(java中的位操作)
前言
讲二进制的东西,必须要说明是多少位机器,八位机上的 1000 1000
和 十六位机上的 1000 1000
,那能是一回事嘛,差远了。
我用 java
中的规范来讲这个知识,一来我是写 java
的,二来忘记了大一那时候学C
的情况,也不想考察C
或C艹
,int
,这些数据类型跟机器位数的关系。
机器数
可以理解为给我们人看的二进制,注意计算机中保存数据用的二进制,根本不是这个机器数,而是后面说的 补码 ;
比如,数字 3 ,在 java
中整数,默认是 int
类型,占用4
个字节,所以,它的机器数是 0000 0000,0000 0000,0000 0000,0000 0011
;
数字 -3 的机器数: 1000 0000,0000 0000,0000 0000,0000 0011
;
在二进制中,最高位是符号位,0 代表正数,1 代表负数,其中符号位是不参与进位的 ;
真值
就是除去符号位,剩下的位的二进制转成十进制,再配上正负号的值。我们要看一串 0101001010
,是看它真值的,而不是看他二进制直接转成十进制是多少。
比如, 1000 0000,0000 0000,0000 0000,0000 0011
的真值是 -3 ,二进制直接转成十进制却是 2147483651 。
原码
原码跟机器数是一样的。
还是数字 3
原码是 0000 0000,0000 0000,0000 0000,0000 0011
;
数字 -3
原码是 1000 0000,0000 0000,0000 0000,0000 0011
;
正数、负数的原码都是机器数。
反码
还是数字 3
原码是 0000 0000,0000 0000,0000 0000,0000 0011
;
反码是 0000 0000,0000 0000,0000 0000,0000 0011
;
数字 -3
原码是 1000 0000,0000 0000,0000 0000,0000 0011
;
反码是 1111 1111,1111 1111,1111 1111,1111 1100
;
正数的原码和反码是一样的。负数的反码是由原码保存符号位不变,其他位取反得到的。
补码
还是数字 3
原码是 0000 0000,0000 0000,0000 0000,0000 0011
;
反码是 0000 0000,0000 0000,0000 0000,0000 0011
;
补码是 0000 0000,0000 0000,0000 0000,0000 0011
;
数字 -3
原码是 1000 0000,0000 0000,0000 0000,0000 0011
;
反码是 1111 1111,1111 1111,1111 1111,1111 1100
;
补码是 1111 1111,1111 1111,1111 1111,1111 1101
;
正数的原码和反码是一样的。负数的补码是由反码 +1,得到的,并且这个加法操作产生的进位,不能进位到符号位。
计算机中保存的都是补码
比如 -3,看下它对应的二进制数据。
因此,看到一个二进制数,想要知道它表示的数值是多少,其实就是求其真值的过程。
但是有特殊的存在,比如补码是 1000 0000,0000 0000,0000 0000,0000 0000
,这种符号位为 1,其他位全是 0 的存在,是没有反码、原码的。它们表示的值,是除符号位为 0,其他位为 1 的 0111 1111,1111 1111,1111 1111,1111 1111
的真值 +1 的相反数 。
给你一个二进制,要看看它是什么,才能准确的说出什么。
位操作
前面讲那么多,引入正题,java
中的位操作。
便于理解,我们这里说的一个十进制数的二进制形式都是 补码
,不是原码,不是我们常规看到的二进制直接转十进制!毕竟,计算机位运算的时候,也是直接补码来的
>>
无符号右移规则:
- 符号位不变
- 高位补符号位的数值,即符号位是 1 ,就补充 1,反之亦然 。
- 数值上的变化是,模运算 ,移动几位,就模 2 的几次方(在没有溢出的情况下) ;
- 如果移动的位数,超过了数据本身的位数,则实际移动的位数是当前位数的取模;
byte
类型的 -128 ,右移动 2 位:1000 0000
>> 2 =1110 0000
= -32<<
有符号右移动规则:
- 符号位跟随移动
- 低位补 0 。
- 数值上的变化是,乘法,移动几位,就乘以 2 的几次方 ;
- 重要的一个规则,如果数据类型是
byte、short
会被自动的提升到int
类型。 - 提升后的数据类型,多出来的高位,全部用符号位填充。
- 如果移动的位数,超过了数据本身的位数,则实际移动的位数是当前位数的取模;
byte
类型的 -128 ,左移动 2 位:1000 0000
<< 2 =1111 1111,1111 1111,1111 1111,1000 0000
<< 2 =1111 1110 0000 0000
= -512 ;byte
类型的 -128 ,左移动 62 位,其实是左移动 62 % 32 = 30 位:1000 0000
<< 62 =1111 1111,1111 1111,1111 1111,1000 0000
<< 30 =0000 0000,0000 0000,0000 0000,0000 0000
= 0 ;>>>
无符号右移动规则:
- 符号位跟随移动
- 高位补 0 。
byte
类型的 -128 ,无符号右移 2 位:1000 0000
>>> 2 =0010 0000
= 32 ;
主要记住一个对右操作数取模运算。
强制转换,精度丢失
类似于xx=
这样的操作符号,比如 >>=、<<=、+=,-=
,底层是有个强制转换的;
最简单的:
byte a = 127 ;
byte b = a + 10 ; // error 数据类型溢出
a += 10 ; // ok ,底层被类型强制转换了
移位也是一样的:
byte b = -64;
System.out.println(b<<3); // 值是 -512
System.out.println(b<<=3); // 被强制转换以后,只取低8位,值是 0
二进制知识(java中的位操作)的更多相关文章
- 深入Java中的位操作
「WTF系列」深入Java中的位操作 关于WTF系列 引 学完本章节你将学会位的基础概念与语法,并且还会一些骚操作!! 与.或.非.位移 原码.反码.补码 字节.位.超区间...... 开始本章节之前 ...
- java中的位操作
之前做项目的时候使用位操作不是很多,今天在刷leetcode上题目的时候用到了位操作,是leetcode中的第29题Divide Two Integers. 一.java的位操作: 位运算表达式由操作 ...
- 二进制之Java中的进制(二)
1. jdk中的进制转换 十进制转十六进制 Integer.toHexString(int i); 十进制转八进制 Integer.toOctalString(int i); 十进制转二进制 Inte ...
- java中无符号类型的处理
在Java中,不存在Unsigned无符号数据类型,但可以轻而易举的完成Unsigned转换. 方案一:如果在Java中进行流(Stream)数据处理,可以用DataInputStream类对Stre ...
- (转)java 中unsigned类型的转换
转自:http://blog.sina.com.cn/s/blog_77bf45a90101dld9.html 在Java中,不存在Unsigned无符号数据类型,但可以轻而易举的完成Unsigned ...
- JAVA中常用的二进制位操作
一,计算某个正数的二进制表示法中 1 的个数 //求解正数的二进制表示法中的 1 的位数 private static int countBit(int num){ int count = 0; fo ...
- Java中的二进制及基本的位运算
Java中的二进制及基本的位运算 二进制是计算技术中广泛采用的一种数制.二进制数据是用0和1两个数码来表示的数.它的基数为2,进位规则是"逢二进一",借位规则是"借一当二 ...
- java中关于IO流的知识总结(重点介绍文件流的使用)
今天做软件构造实验一的时候,用到了java文件流的使用,因为之前学的不是很踏实,于是决定今天好好总结一下, 也方便以后的回顾. 首先,要分清IO流中的一些基础划分: 按照数据流的方向不同可以分为:输入 ...
- 二进制原码、反码、补码以及Java中的<< 和 >> 和 >>> 详细分析
1.计算机二进制系统中最小单位bit 在计算机二进制系统中: bit (位) :数据存储的最小单元. 简记为b,也称为比特(bit),每个二进制数字0或1就是一个位(bit),其中,每 8bit = ...
随机推荐
- 开放-封闭原则(OCP)
怎样的升级才能面对需求的改变却可以保持相对稳定,从而使得系统可以在第一个版本以后不断推出新的版本呢?开放-封闭原则(The Open-Closed Principle, OCP)为我们提供了指引.软件 ...
- Ubuntu16.04忘记MySQL5.7的root用户密码之解决方案
其实也就四步,如下: 修改配置文件 sudo vimi /etc/mysql/mysql.conf.d/mysqld.cnf 并在 在[mysqld]下方的skip-external-locking下 ...
- Control.ImeMode属性简释
在WINFORM中,我们经常遇到如下问题.文本输入框中输入法有时候需要被禁用,或者某些时候全半角输入自动转换.查阅相关资料,现小结如下. (一)Control.ImeMode 属性:获取或设置控件的输 ...
- 2019软工实践_Alpha(3/6)
队名:955 组长博客:https://www.cnblogs.com/cclong/p/11872693.html 作业博客:https://edu.cnblogs.com/campus/fzu/S ...
- Ubuntu 命令行连接WiFi
查看是否已经正确安装无线网卡 iwconfig .启动无线网卡, 如果网卡是wlan0 # 方式1 ifconfig wlan0 up # 或者方式2 ip link set wlan0 up .扫描 ...
- 什么是epistatic effects | 上位效应
epistatic与interaction之间的区别与联系? genetic上的interaction是如何定义的? Epistasis is the phenomenon where the eff ...
- 多层nginx中的压缩问题 api接口>1M数据的返回浏览器 网关
基础 前端异步请求,局部刷新,加大最大等待时间 nginx开启压缩 进阶 多级nginx的压缩 实践测试: 每级都要开启压缩 gizp on: 最外层开启,但最内层没有开启 最外层没有开启 最外层.最 ...
- Centos 安装 nginx 特定版本
CentOS 6.9/7通过yum安装指定版本的Nginx - EasonJim - 博客园https://www.cnblogs.com/EasonJim/p/9020896.html [root@ ...
- PHP 构造函数和析构函数
构造函数 __construct ([ mixed $args [, $... ]] ) : void PHP 5 允行开发者在一个类中定义一个方法作为构造函数.具有构造函数的类会在每次创建新对象时先 ...
- grib2文件格式说明
GRIB是一种二进制编码的名称,用于加工资料的传输和交换,GRIB编码的分析或预报产品是由一系列八位组构成的连续比特流组成.在GRIB2中编码资料主要分为9段. 0段——指示段八位组序号 ...