二进制那些事

理清字符集和字符编码关系中介绍到计算机内部由集成电路决定了计算机的信息只能用二进制数处理。本期将介绍二进制那些事。

移位运算

移位运算指的是将二进制数值的各数位进行左右移位的运算。左移空出来的低位要进行补0操作,右移空出来的高位要进行怎样的操作,我们会在后面说明。

我们发现,左移两位相当于对39乘以4,右移两位相当于除4,也就是说计算机用移位算法来表示数据的乘除运算。

补数

刚才之所有没有介绍相关右移的内容,是因为用来填充右移后空出来的高位的数值,有 0 和 1 两种形式。要想区分什么时候补0什么时候补1,只要掌握了用二进制数表示负数的方法即可。

二进制数中表示负数时,一般会把最高位作为符号来使用,也就是说,最高位是符号位。正数的符号位用0表示,负数的符号位用1表示。举个栗子,1的二进制数是0000 0001 ,那么,-1的二进制数是多少呢?难道是1000 0001,1000 0001+0000 0001 结果不是0,说明这个结果是错的。为此,在表示负数时就需要使用补数。补数就是用正数表示负数,通过将二进制数的各位数值全部取反,然后再将结果加1得到补数。-1的补数是1111 1111。同理,1111 1110表示的负数是多少呢?这时我们可以利用负负得正这个性质。假设1111 1110是负xx,那么1111 1110的补数是正xx。1111 1110的补数是0000 0010,因此1111 1110表示-2。

逻辑右移和算术右移

在介绍完补数后,让我们返回到右移这个话题,右移之后在最高位有补0和补1两种情况。当二进制数的值表示图形模式而非数值时,移位后在最高位补0,这是逻辑右移。将二进制数值作为带符号的数值进行运算时,移位后要在最高位填充前符号位的值( 0 或 1 ),这是算术右移。

现在我们来看一个右移的例子。将-8(1111 1000)右移两位。这时,逻辑右移的情况下结果会是 0011 1110,也就是十进制数62,显然不是-2,而在算术右移的情况下,结果会变成1111 1110 ,用补数表示就是-2,和真实结果相同。需要注意的是只有在右移时才区分逻辑移位和算术移位。

二进制数表示小数

通过上述介绍,我们对整数的二进制表示方式做了说明。由于计算机内部所有信息都是以二进制数的形式来处理,因此在这一点上,整数和小数并无差别。不过,使用二进制数表示整数和小数的方法却有很大的不同。

由于二进制数表示的小数的数值范围是有限的,并不能表示所有的十进制小数。例如:小数点后3位用二进制数表示时的数值范围为0.000~0.111,但是只能表示有限的十进制小数,如下图所示。

为了加深大家印象,举一个更加实际的栗子:将0.1累加100次最终结果是10.000002,不是10。

public class TestBinary {
    public static void main(String[] args) {
        float sum=0.0f;
        for (int i = 0; i < 100; i++) {
            sum += 0.1;
        }
        System.out.println(sum);

    }
}

浮点数

现在,我们应该知道仅仅依靠纸面上的二进制数是表示不了全部小数。那么,计算机实际上是以什么样的表现形式来处理小数的呢?

目前,计算机提供了单精度浮点数和双精度浮点数来表示小数形式。单精度浮点数用32位表示全体小数,而双精度浮点数用64位表示。它们都是由符号、尾数和指数组成。

接下来,让我们一起看一下如果将0.1用单精度浮点数来表示,累加100次的结果是否是10,可以结果又一次出乎意料,结果是10.000002。

    public static void main(String[] args) {
        float sum=0.0f;
        float step = 0.1f;
        for (int i = 0; i < 100; i++) {
            sum += step;

        }
        System.out.println(sum);

    }
}

如何避免计算机计算出错

我们知道,无论是用纸面二进制还是浮点数表示小数,都存在计算出错的可能性,那么我们该如何避免这种问题呢?

首先是回避策略,即无视这些问题。有时候一些微小的偏差并不会造成什么问题。其次,把小数转换成整数来计算。还是以0.1累加100次为例,将0.1扩大10倍后累加100次,最后把结果除以10就可以了。

public class TestBinary {
    public static void main(String[] args) {
        int sum=0;
        int step = 1;
        for (int i = 0; i < 100; i++) {
            sum += step;

        }
        System.out.println(sum/10);

    }
}


欢迎关注微信公众号:木可大大,所有文章都将同步在公众号上。

原文地址:https://www.cnblogs.com/neal-ke/p/8870091.html

时间: 2024-08-29 11:58:08

二进制那些事的相关文章

Android桌面快捷方式那些事与那些坑

原文来自http://blog.zanlabs.com/2015/03/14/android-shortcut-summary/ 将近二个多月没写博客了. 之前一段时间一直在搞红包助手,就没抽时间写博客,但写这个真的是很好玩.没想到居然在Android上实现模拟点击,从而实现自动抢红包,有兴趣的同学可以参考https://github.com/waylife/RedEnvelopeAssistant ,代码已经开源. 红包助手还有一些问题,但是现在基本的抢红包基本没问题了.目前正在对它进行优化以

BLOB存储图片文件二进制数据是非对错

子在一天一天虚度,生活也在一天一天中茫然 做人做事哪能尽如人意,付出多少收获多少虽然存在偏颇,但是不劳而获的心态是万万不对的,更不能去怨天尤人,低调为人.做好自己就可以了 改进你的系统的最好的方法是先避免做“蠢事”.我并不是说你或你开发的东西“蠢”,只是有些决定很容易被人们忽略掉其暗含的牵连,认识不到这样做对 系统维护尤其是系统升级带来多大的麻烦.作为一个顾问,像这样的事情我到处都能见到,我还从来没有见过做出这样的决定的人有过好的结果的. 图片,文件,二进制数据 既然数据库支持 BLOB 类型的

中标麒麟学习笔记3:试验制作wireshark二进制安装包

Wireshark是个优秀的网络包嗅探工具,对于学习理解网络知识有很大的帮助.中标麒麟桌面版本没有集成这一软件,所以想自己试着安装并学习一下如何制作RPM包. 学习了<fedora官网RPM包制作指南>后,觉得事情比较简单,主要就是编辑一个SPEC配置文件嘛,加上configure.make.make  install等指令,修改修改描述说明什么的就完活了.于是想先找个wireshark源码包,再找一个现成的SPEC文件,比如fedora21的SRPM包中就有,然后稍作修改就可以用rpmbui

OpenNLP:驾驭文本,分词那些事

OpenNLP:驾驭文本,分词那些事 作者 白宁超 2016年3月27日19:55:03 摘要:字符串.字符数组以及其他文本表示的处理库构成大部分文本处理程序的基础.大部分语言都包括基本的处理库,这也是对文本处理或自然语言处理的前期必要工作.典型代表便是分词.词性标注.句子识别等等.本文所介绍的工具主要针对英文分词,对于英文分词工具很多,笔者经比较Apache OpenNLP效率和使用便捷度较好.另外其针对Java开发提供开源的API.开篇简介OpenNLP的情况,随后介绍6种常用模型,最后针对

【转】CPU与内存的那些事

下面是网上看到的一些关于内存和CPU方面的一些很不错的文章. 整理如下: 转: CPU的等待有多久? 原文标题:What Your Computer Does While You Wait 原文地址:http://duartes.org/gustavo/blog/ [注:本人水平有限,只好挑一些国外高手的精彩文章翻译一下.一来自己复习,二来与大家分享.] 本文以一个现代的.实际的个人电脑为对象,分析其中CPU(Intel Core 2 Duo 3.0GHz)以及各类子系统的运行速度——延迟和数据

java解惑之常常忘记的事

java解惑之常常忘记的事 2012-10-17 18:38:57|  分类: JAVA |  标签:基础知识  软件开发  |举报|字号 订阅 针对刚接触java的菜鸟来说,java基础知识都是我们必须认真学习的,但是在工作过几年时间的老鸟来说,有时候也会对java的基础知识产生疑问,对于这种不确定,并且很容易混淆的知识点,java解惑已经为大家进行了很好的总结,现在借用一个作者的总结,进行一下罗列,希望能对你有所帮助. 1. 奇偶判断 不要使用 i % 2 == 1 来判断是否是奇数,因为i

关于 MySQL 密码你应该知道的那些事

关于 MySQL 密码你应该知道的那些事 提交 我的评论 加载中 已评论 关于 MySQL 密码你应该知道的那些事 2015-07-23 Linux中国 Linux中国 Linux中国 微信号 linux-cn 功能介绍 面向Linux爱好者,提供Linux技术文章.新闻资讯和交流平台. 每天推送一条最新精选Linux资讯和技术文章:支持Linux命令查询.Linux资讯搜索及微信群的交流. 本文将介绍MySQL用户密码相关的一些知识,以及5.6中对于安全性的一些改进 MySQL用户密码是如何生

图片上传那些事

简述: 一个项目上,之前已经做好了用flash上传图片的功能,但是现在因为客户端的限制,要求不用flash,可以使用html5,于是改造开始了. 先给出之前flash的界面: 需求:  上面的图片里面可以看出三个需求: 1. 文件选择按钮外观需要美化 2. 可以预览图片 3. 上传图片(上传后的图片存在形式需要与之前flash上传的一样,也就是说需要byte[]的形式) 用户上传图片之后,需要把新的图片显示到其他位置,所以还有一个需求: 4. 上传成功后调用回调函数 思考: 1. 文件选择按钮外

PL/SQL数据库开发那点事

PL/SQL数据库开发那点事-->编程,存储程序 在SQL*plus 中编写PL/SQL程序,并在SQL*plus 中执行它, PL/SQL块的代码就存放在SQL*plus的缓冲区中.如果在SQL*plus 中执行了其他的SQL语句或PL/SQL块,缓冲区中就会存放新的代码,原来的PL/SQL块就会被从缓冲区中清除出去.这种没有名称只是临时存放在缓冲区中的PL/SQL块叫做匿名块.匿名块就是没有名字的PL/SQL块,它仅存放在缓冲区中,只能在当前SQL*plus环境中执行.如果希望PL/SQL块