资讯专栏INFORMATION COLUMN

java位运算和字节编码(一)

Dongjie_Liu / 2118人阅读

摘要:正数的原码,反码和补码相同。变量原码反码是符号位不变,其他位取反反码补码则是在反码的基础上加补码所以在计算机中正确的表示应该是。原码反码补码此刻开始转换为类型,占个字节,符号位,用填充高位三个字节。

我们都知道计算机存储的是二进制,长度是8个比特。

byte b = 10;
int i = -10;
long l = 10L;

那么以上几个变量如何用二进制表示呢?
很多人第一印象肯定是 b变量占用一个字节,也就是8位,所以 b用二进制表示就是 1010,高位补零,所以是 00001010。那么i是int,占用4个字节,也就是32位,但因为是负数,所以最高位是100000000 00000000 00000000 00001010。同理 l变量则是 00000000 00000000 00000000 00000000 000000000 00000000 00000000 00001010。

上面的推理过程中存在一处错误,就是在java中存储的是补码,而不是原码。正数的原码,反码和补码相同。负数则不是一样。以上面 int i = -10 作为例子。

变量 i
原码 1000 1010
# 反码是符号位不变,其他位取反
反码 1111 0101
#补码则是在反码的基础上加1
补码 1111 0110

所以-10 在计算机中正确的表示应该是 1111 0110。
上面我们已经学习原码,反码和补码相关的概念,至于为什么要用补码,感兴趣的可以自己去查。

我们也知道在网络传输中,存储的就是二进制相关的byte数组。那么现在我们需要往消息中写入int或者long相关的信息,如何转换为byte数组中的相关项?第一个想到的办法就是强制转换。

int x = 135;
System.out.println((byte)x);  /** 输出-121 **/

x = -135;
System.out.println((byte)x); /** 输出-121 **/

可见输出的答案并不如你所愿。想知道为什么这样吗?感兴趣的可以自己去推导。
额,还是帮你们推导一遍吧。我们以 -135为例。
首先我们知道 int 占用4个字节,而byte占用1个字节,同时你也看到 -135已经超出了一个字节所能表示的范围[-128, 127]。如果强制转换后还能显示出正确结果,那才恐怖啊。

-135

原码 10000000 00000000 00000000 10000111

反码 11111111 11111111 11111111 01111000

补码 11111111 11111111 11111111 01111001

我们知道java中存储的是补码,可是因为byte只占一个字节,所以转换的时候只取到最低位那个字节也就是 01111001作为转换后补码存在。因为正数的原码和补码相同,也即是这个字节的原码是01111001,原值是 121。

刚才我们讨论的是int强制转换成byte类型可能存在的问题。那么如果我需要把byte类型的强制转换成int类型的会出现什么样的问题。

byte num = 120;        
System.out.println((int)num); 
num = -120;
System.out.println((int)num);

大家看到这两行示例代码时。尽量自己尝试推导出结果来,不要看我下面的推导过程。
我们以-120作为例子,尝试推导下(看到没有,我喜欢负数)。

-120

原码 11111000

反码 10000111

补码 10001000

##此刻开始转换为int类型,占4个字节,符号位1,用1填充高位三个字节。如果符号位是0,高位会用0填充。

补码 11111111 11111111 11111111 10001000 /** 存储在内存中的int整形补码 **/
反码 11111111 11111111 11111111 10000111
原码 10000000 00000000 00000000 01111000 
原值 -120

所以 当 byte num = -120 时, (int)num = -120
我相信很多人都没有自己推导,直接看我的推导的。那么再给你个机会,尝试推导下当byte num = 120的时候推导过程。

通过byte强制转换成int 好像一切都很顺利,也没有int强制转换成byte相关的问题。
当真的是那样吗?下一篇我们继续探讨这个话题。

原文链接 http://segmentfault.com/a/1190000003758605/

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/64539.html

相关文章

  • java运算字节编码(二)

    摘要:虽然发生了符号位扩展,但是没有任何问题。这就是计算机中原码和补码的奥秘之处。不过等你看懂了就会发现位运算的巧妙之处。这个函数的作用呢其实就是计算整形变量高位连续为零的个数。比如时二进制补码就是原码也就是,那么得到的结果应该是。 上一篇文章我们讨论到byte强制转换成int。然后抛出了一个问题,就是byte直接强制转换成int一定会没问题吗?还是因为上面我们推导的那个例子只是个特例。好吧...

    jerry 评论0 收藏0
  • Java编程基础02——Java语言基础

    摘要:所以就想把一大串缩短点,将二进制中的三位用一位表示。以可以大写也可以小写开头版本可以表示二进制了八进制的数据表现形式由组成。结果把系数基数的权次幂相加即可。因为语言采用的是码来编码的。 1_(常量的概述和使用)* A:什么是常量(constant) 在程序执行的过程中其值不可以发生改变 B:Java中常量的分类 字面值常量 自定义常量(面向对象部分讲) C:字面值常量的...

    pakolagij 评论0 收藏0
  • Java各种数据类型,自己学习写的笔记!!!

    摘要:局部变量声明在函数内部的变量。在作用域范围内不能出现命名冲突。 java编程规范: 1.良好的标识符的命名 保留字不能作为标识符命名: class、public、static..., goto,const 区分大小写:helloWorld、HelloWorld 2.良好的注释习惯 3.良好的缩进:没遇到一个代码块缩进一次(一个tab键) 变量:代...

    stefanieliang 评论0 收藏0
  • python第

    摘要:解释器的种类的官方版本,使用语言实现,使用最为广泛,实现会将源文件文件转换成字节码文件文件,然后运行在虚拟机上。与类似特殊实现的,将的字节码字节码再编译成机器码。用于跳出当前循环,继续下一次循环。 python介绍 python的用途 我们为什么学习python,python学会了可以做什么,从一个例子告诉我们学习一门编程语言的好处。如:公鸡5文钱一只,母鸡3文钱一只,小鸡3只一文钱,...

    邱勇 评论0 收藏0
  • killBase系列 -- 密码学(

    摘要:系列密码学二传送门密码学一基础密码学算法分类消息编码消息摘要类,类,对称密码非对称密码数字签名五元组明文原始信息。非对称密码包提供给,,等非对称加密算法。对称加密算法在分布式网络系统上使用较为困难,主要是因为密钥管理困难,使用成本较高。 前言 最近一场面试,面试官问了我 对称加密与非对称加密的问题,虽然曾经看过一些内容,但是没有系统的整理,所以当被问的时候,脑子里一片空白,没有回答上...

    tomato 评论0 收藏0

发表评论

0条评论

Dongjie_Liu

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<