Knowledge Point 20180305 补位的两种方式
我们都知道Java的基本数据类型内存中都有一个固定的位数(内存分配空间),如byte占8位,int占32位等。正因如此,当把一个低精度的数据类型转成一个高精度的数据类型时,必然会涉及到如何扩展位数的问题。这里有两种解决方案:
(1)补零扩展:填充一定位数的0。
(2)补符号位扩展:填充一定位数的符号位(非负数填充0,负数填充1)。
对于无符号类型(相当于都是非负数)与有符号类型中的非负数部分,这两种方法没有区别,都是填充0;对于有符号类型中的负数部分,这两种方法就会产生差异了,补零扩展会填充0,而补符号位扩展会填充1。下面将byte类型的-127转为int类型为例,探讨一下这两种方法的区别。
首先必须明确一些知识点:
- 计算机是用补码来存储数字的;(关于补码可以了解本人另一篇文章:数据在计算机中的表示)
- 正数的补码等于原码;
- 负数的补码等于反码+1;
- 一个数的补码的补码等于原码。
-127原码1111 1111,反码1000 0000,补码1000 0001。计算机存储的是1000 0001,用十六进制表示为0x81。
当使用补零扩展时,结果为: 0000 0000 0000 0000 0000 0000 1000 0001
用十六进制表示为0x81。为了计算十进制值,计算它的补码,结果为: 0000 0000 0000 0000 0000 0000 1000 0001
将这个二进制数转成十进制(相关的进制转换详情查看机器数转换与进制转换)的结果是129。
当使用补符号位扩展时,结果为: 1111 1111 1111 1111 1111 1111 1000 0001
用十六进制表示为0xFFFFFF81。为了计算十进制值,计算它的补码,结果为: 1000 0000 0000 0000 0000 0000 0111 1111
将这个二进制数转成十进制的结果是-127。
由此可以得出结论:
(1)使用补零扩展能够保证二进制存储的一致性,但不能保证十进制值不变。
(2)使用补符号位扩展能够保证十进制值不变,但不能保证二进制存储的一致性。
下面以Java为例进行验证(Java中没有无符号类型,只有有符号类型):
public static void main(String[] args){
byte b = -127;
System.out.println(Integer.toBinaryString((int)b));
System.out.println(Integer.toBinaryString((int)(b & 0xFF)));
}
& 是按位与运算符 ,0xff二进制就是1111 1111。& 运算是,如果对应的两个bit都是1,则那个bit结果为1,否则为0.
比如 1010 & 1101 = 1000 (二进制)
由于0xff最低的8位是1,因此number中低8位中的&之后,如果原来是1,结果还是1,原来是0,结果位还是0.高于8位的,0xff都是0,所以无论是0还是1,结果都是0。
输出:
11111111111111111111111110000001
10000001
由此又可以得出结论:
(1)对于有符号类型,Java使用的是补符号位扩展,这样能保证十进制的值不变;
(2)如果想要用补零扩展来确保二进制的内容不变,可以通过& 0xFF(不一定是8位,根据待转换的数据位数而定)实现。本质是将前面补上的1都通过与运算改成了0。
关于b & 0xFF为什么会导致结果改变的问题,是因为byte在进行这个运算之前先转换为了默认类型int,后面的0xFF也进行了相应的位扩展,通过补充符号位,计算如下:
11111111111111111111111110000001
&
00000000000000000000000011111111
||
00000000000000000000000010000001
这里就是补码的两种方式,了解了这个有助于我们了解精度的问题;
注:文章参考http://blog.csdn.net/swt369/article/details/77931936
Knowledge Point 20180305 补位的两种方式的更多相关文章
- Struts2实现ajax的两种方式
基于Struts2框架下实现Ajax有两种方式,第一种是原声的方式,另外一种是struts2自带的一个插件. js部分调用方式是一样的: JS代码: function testAjax() { var ...
- CSharpGL(18)分别处理glDrawArrays()和glDrawElements()两种方式下的拾取(ColorCodedPicking)
CSharpGL(18)分别处理glDrawArrays()和glDrawElements()两种方式下的拾取(ColorCodedPicking) 我在(Modern OpenGL用Shader拾取 ...
- 两种方式实现java生成Excel
Web应用中难免会遇到需要将数据导出并生成excel文件的需求.同样,对于本博客中的总结,也是建立在为了完成这样的一个需求,才开始去了解其实现形式,并且顺利完成需求的开发,先将实现过程总结于此.本博文 ...
- Android ScrollView监听滑动到顶部和底部的两种方式(你可能不知道的细节)
Android ScrollView监听滑动到顶部和底部,虽然网上很多资料都有说,但是不全,而且有些细节没说清楚 使用场景: 1. 做一些复杂动画的时候,需要动态判断当前的ScrollView是否滚动 ...
- 在基于MVC的Web项目中使用Web API和直接连接两种方式混合式接入
在我之前介绍的混合式开发框架中,其界面是基于Winform的实现方式,后台使用Web API.WCF服务以及直接连接数据库的几种方式混合式接入,在Web项目中我们也可以采用这种方式实现混合式的接入方式 ...
- (转)SqlServer 数据库同步的两种方式 (发布、订阅),主从数据库之间的同步
最近在琢磨主从数据库之间的同步,公司正好也需要,在园子里找了一下,看到这篇博文比较详细,比较简单,本人亲自按步骤来过,现在分享给大家. 在这里要提醒大家的是(为了更好的理解,以下是本人自己理解,如有错 ...
- 《连载 | 物联网框架ServerSuperIO教程》- 10.持续传输大块数据流的两种方式(如:文件)
1.C#跨平台物联网通讯框架ServerSuperIO(SSIO)介绍 <连载 | 物联网框架ServerSuperIO教程>1.4种通讯模式机制. <连载 | 物联网框架Serve ...
- Xamarin Android Activity全屏的两种方式
方式一 直接在Activity的Attribute中定义 如下 在 MainActivity 中 [Activity(Label = "app", MainLauncher = t ...
- placeholder实现的两种方式
/** * PlaceHolder组件 * $(input).placeholder({ * word: // @string 提示文本 * color: // @string 文本颜色 * evtT ...
随机推荐
- 使用PowerShell批量解除锁定下载的文件
使用PowerShell批量解除锁定下载的文件 3.在需要解锁的文件所在的文件夹中空白处,按住Shift然后单击右键,在弹出的右键菜单中,选择“在此处打开PowerShell窗口”, 输入Get-Ch ...
- 深入理解ES6之函数
一:关于函数的参数: 可以接受任意数量的参数而无视函数声明的参数数量是js函数的独特之处. 1:参数默认值 ES6之前做法: function makeRequest(url,timeout,call ...
- Hibernate Annotation (Hibernate 注解)
简介: 传统上,Hibernate的配置依赖于外部 XML 文件:数据库映射被定义为一组 XML 映射文件,并且在启动时进行加载. 然而现在借助新的 Hibernate Annotation 库, ...
- HDD 机械硬盘 安装 linux(centos7)
1. 下载 UltraISO 文件-->打开, 选中centos.iso镜像; 启动-->写入硬盘映像-->硬盘驱动器(选中u盘)写入方式(USB-HDD+v2)-->写入 ...
- 关于圆角border-radius
一.border-radius 可以同时设置1-4个值 a)1个值 控制4个圆角 b)2个值 第1个控制左上角和右下角 第2个值控制左下角和右上角 c)3个值 第1个控制 第2个值控制左 ...
- Common in Hardware & Software
A lot of common in Hardware programming & Software Programming
- GIT团队合作探讨之四--不同工作流优缺辨析
由于git非常强大,它可以支持非常多的协作模式,而可能正因为选择太多反而有时候对于我们如何开始开展团队协作无从下手.本文试图阐述企业团队中应用最为广泛的git 工作流,为大家理清思路,最大限度发挥gi ...
- python 图形界面
Python自带的库是支持Tk的Tkinter,使用Tkinter,无需安装任何包,就可以直接使用. Tk是一个图形库,支持多个操作系统 导入Tkinter包的所有内容: from tkinter i ...
- LVM逻辑卷的管理和使用
本篇将从头到尾演示一遍逻辑卷的管理. 主要步骤 1.创建lv逻辑卷步骤 前提:先创建3个磁盘分区,类型为8e: 1.PV创建 pvcrete /dev/ ...
- CSV 文件读写
转自:http://www.cnblogs.com/Clin/archive/2013/03/14/2959022.html public class CSVFileHelper { /// < ...