二进制那些事
admin
2023-07-27 20:00:05
0

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

移位运算

移位运算指的是将二进制数值的各数位进行左右移位的运算。左移空出来的低位要进行补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 class TestBinary {
    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);

    }
}

相关内容

热门资讯

浙江宣传:“走个面儿”咋就没面... “咱北京两千多万人口,您受累,您走个面儿,把这第一波的票房带起来,咱就有了。”某知名导演的新片首映礼...
辞职声明仅95秒遭质疑,韩国队... 【环球时报综合报道】美加墨世界杯小组赛出局后,韩国队主教练洪明甫当地时间28日在墨西哥的韩国队大本营...
美媒爆料:美军第五舰队总部遭伊... 据美国《华尔街日报》27日报道,其通过对卫星图像、社交媒体视频和五角大楼记录的分析发现,今年2月底至...
英国智库给菲律宾GDP增速“浇... 【环球时报特约记者 叶满】英国经济研究机构凯投宏观发布的最新一期《亚洲经济展望》报告(以下简称“报告...
欧洲持续高温,有华人用冰箱降温... 连日来,欧洲多国迎来罕见极端高温天气,法国、德国、意大利等地气温持续飙升,部分地区突破40摄氏度。受...
伊副外长强调船只须按“伊朗线路... 伊朗外交部副部长加里巴巴迪当地时间29日晚间在接受采访时强调,所有船只均须按照“伊朗线路”通过霍尔木...
委内瑞拉强震已致1719人死亡 当地时间29日,委内瑞拉全国代表大会主席罗德里格斯通报,地震已造成该国1719人死亡,5034人受伤...
铋晟新材料申请氯氧化铋基复合材... 国家知识产权局信息显示,江苏铋晟新材料有限公司申请一项名为“一种氯氧化铋基复合材料及其制备方法和用途...
韩国政府将投资千万亿韩元于AI... 韩国总统李在明29日在总统府青瓦台主持召开会议,公布总额超千万亿韩元的半导体、物理人工智能(AI)和...
以色列防长称以伊可能随时再起冲... △卡茨(资料图)据以色列方面29日消息,以国防部长卡茨当天表示,鉴于复杂的安全局势和在黎巴嫩的军事行...