首页 > 其他分享 >DAY001_二进制运算

DAY001_二进制运算

时间:2023-08-12 21:25:50浏览次数:39  
标签:00000000000000000000000000000000 11111111111111111111111111111111 运算 二进制 补码 Syst

左移和右移

无符号左移? Java没有无符号左移
无符号右移 左边补0
有符号右移 左边用原符号位补位 即正数补0效果同无符号右移、负数补1
有符号左移 右边补0
import org.junit.Test;

public class TestAaaBinary {

	@Test
	public void test01() {
		//调用 JDK 的自带方法 toBinaryString 输出二进制数
		test01(false);
		//自己写的打印,结果与上面是一样的
		test01(true);
	}

	private void test01(boolean print) {
		int num_5 = 5;
		int num_5_2 = -5;

		System.out.println("无符号右移:正数");
		for (int i = 0; i < 5; i++) {
			print(num_5 >>> i, print);
		}
		System.out.println("无符号右移:负数");
		for (int i = 0; i < 5; i++) {
			print(num_5_2 >>> i, print);
		}
		System.out.println("有符号右移:正数");
		for (int i = 0; i < 5; i++) {
			print(num_5 >> i, print);
		}
		System.out.println("有符号右移:负数");
		for (int i = 0; i < 5; i++) {
			print(num_5_2 >> i, print);
		}
		System.out.println("有符号左移:正数");
		for (int i = 0; i < 32; i++) {
			print(num_5 << i, print);
		}
		System.out.println("有符号左移:负数");
		for (int i = 0; i < 32; i++) {
			print(num_5_2 << i, print);
		}
	}

	private void print(int x, boolean print) {
		if (print) {
			print(x);
		} else {
			System.out.println(Integer.toBinaryString(x));
		}
	}

	/**
	 * 输出十进制数的二进制格式
	 */
	private void print(int num) {
		for (int i = 31; i >= 0; i--) {
			System.out.print((num & (1 << i)) == 0 ? "0" : "1");
		}
		System.out.println();
	}
}

输出如下:

无符号右移:正数
00000000000000000000000000000101
00000000000000000000000000000010
00000000000000000000000000000001
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000101
无符号右移:负数
11111111111111111111111111111011
01111111111111111111111111111101
00111111111111111111111111111110
00011111111111111111111111111111
00001111111111111111111111111111
00000111111111111111111111111111
00000011111111111111111111111111
00000001111111111111111111111111
00000000111111111111111111111111
00000000011111111111111111111111
00000000001111111111111111111111
00000000000111111111111111111111
00000000000011111111111111111111
00000000000001111111111111111111
00000000000000111111111111111111
00000000000000011111111111111111
00000000000000001111111111111111
00000000000000000111111111111111
00000000000000000011111111111111
00000000000000000001111111111111
00000000000000000000111111111111
00000000000000000000011111111111
00000000000000000000001111111111
00000000000000000000000111111111
00000000000000000000000011111111
00000000000000000000000001111111
00000000000000000000000000111111
00000000000000000000000000011111
00000000000000000000000000001111
00000000000000000000000000000111
00000000000000000000000000000011
00000000000000000000000000000001
11111111111111111111111111111011
有符号右移:正数
00000000000000000000000000000101
00000000000000000000000000000010
00000000000000000000000000000001
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000101
有符号右移:负数
11111111111111111111111111111011
11111111111111111111111111111101
11111111111111111111111111111110
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111011
有符号左移:正数
00000000000000000000000000000101
00000000000000000000000000001010
00000000000000000000000000010100
00000000000000000000000000101000
00000000000000000000000001010000
00000000000000000000000010100000
00000000000000000000000101000000
00000000000000000000001010000000
00000000000000000000010100000000
00000000000000000000101000000000
00000000000000000001010000000000
00000000000000000010100000000000
00000000000000000101000000000000
00000000000000001010000000000000
00000000000000010100000000000000
00000000000000101000000000000000
00000000000001010000000000000000
00000000000010100000000000000000
00000000000101000000000000000000
00000000001010000000000000000000
00000000010100000000000000000000
00000000101000000000000000000000
00000001010000000000000000000000
00000010100000000000000000000000
00000101000000000000000000000000
00001010000000000000000000000000
00010100000000000000000000000000
00101000000000000000000000000000
01010000000000000000000000000000
10100000000000000000000000000000
01000000000000000000000000000000
10000000000000000000000000000000
00000000000000000000000000000101
有符号左移:负数
11111111111111111111111111111011
11111111111111111111111111110110
11111111111111111111111111101100
11111111111111111111111111011000
11111111111111111111111110110000
11111111111111111111111101100000
11111111111111111111111011000000
11111111111111111111110110000000
11111111111111111111101100000000
11111111111111111111011000000000
11111111111111111110110000000000
11111111111111111101100000000000
11111111111111111011000000000000
11111111111111110110000000000000
11111111111111101100000000000000
11111111111111011000000000000000
11111111111110110000000000000000
11111111111101100000000000000000
11111111111011000000000000000000
11111111110110000000000000000000
11111111101100000000000000000000
11111111011000000000000000000000
11111110110000000000000000000000
11111101100000000000000000000000
11111011000000000000000000000000
11110110000000000000000000000000
11101100000000000000000000000000
11011000000000000000000000000000
10110000000000000000000000000000
01100000000000000000000000000000
11000000000000000000000000000000
10000000000000000000000000000000
11111111111111111111111111111011

此外,根据上面的代码,我们还可以经过测试得出

  • int 类型位移32位、64位还是它本身
  • long 类型位移64位还是它本身

原码&反码&补码

看上面的输出可能会有疑问
整型正数5的二进制是00000000 00000000 00000000 00000101
整型负数5的二进制是10000000 00000000 00000000 00000101
那为什么上文中对于-5的二进制输出是11111111 11111111 11111111 11111011呢?

先公布一下答案:这里输出的都是补码,计算机是使用补码做计算的。

下面详细解释为什么使用补码


计算机中只计算加法

  • 减法可以化为加法:比如5-4转化为5+(-4)
  • 乘法可以转化为加法和位移算法
  • 除法可以先转化为乘法再转化

只算加法简化了电路的设计

但是在二进制运算下,一个正数加上其相反数并不等于0,比如0000 0001 + 1000 0001 = -2

因此出现了反码,而数字本身我们叫做原码

  • 正数的反码是它本身
  • 负数的反码是:符号位不变,其他位取反,比如-5的反码是11111111 11111111 11111111 11111010

反码存在的问题:

  • 比如5 + (-5) = 0,二进制是00000000 00000101 + 11111111 11111010 = 11111111 11111111 全1表示0(负0)
  • 0 + 0 = 0,二进制00000000 00000000全0也表示0(正0)

还有更好的方案吗?答案就是补码

  • 正数的补码是本身
  • 负数的补码是反码+1,例如-5的补码是11111111 11111111 11111111 11111011上文提到过

补码只有全0表示0一种情况,相比反码又简化了电路的设计


参考下面的代码:

public void test02() {
    int num = 5;
    System.out.println("正数5的补码是原码本身");
    print(num);
    System.out.println("正数5取反就是其相反数-5的反码");
    print(~num);
    System.out.println("-5用补码表示,是反码+1");
    print(-num);
}

输出:

正数5的补码是原码本身
00000000000000000000000000000101
正数5取反就是其相反数-5的反码
11111111111111111111111111111010
-5用补码表示,是反码+1
11111111111111111111111111111011

扩展:整型的最大值和最小值

@Test
public void test03() {
    System.out.println("整型最大值是正 2的31次方-1 补码就是其本身");
    print(Integer.MAX_VALUE);
    System.out.println();
    System.out.println("整型最小值的补码");
    print(Integer.MIN_VALUE);
    System.out.println("补码取反");
    print(~Integer.MIN_VALUE);
    System.out.println("补码取反+1 就是整型最小值的相反数 即2的31次方 因此整型最小值是负 2的31次方");
}

输出:

整型最大值是正 2的31次方-1 补码就是其本身
01111111111111111111111111111111

整型最小值的补码
10000000000000000000000000000000
补码取反
01111111111111111111111111111111
补码取反+1 就是整型最小值的相反数 即2的31次方 因此整型最小值是负 2的31次方

标签:00000000000000000000000000000000,11111111111111111111111111111111,运算,二进制,补码,Syst
From: https://www.cnblogs.com/felix-1/p/17625530.html

相关文章

  • 运算符
    运算符%运算符满足公式a%b=a-a/b*b-10%-3=-1++,--运算intj=8;intk=++j;//输出结果都是9Sysout.out.println("j="+j+"k="+k);intj=8;intk=j++;//j等于9,k等于8Sysout.out.println("j="+j+"k="+k);关系运算符......
  • C++ 字符串拼接技巧(stringstream、字符串迭代器、字符串的加法运算符、std::accumulat
    在C++中,经常需要将多个字符串拼接成一个大字符串。这个过程很容易出错,但有一些技巧可以帮助我们轻松地实现这个目标。本文将介绍一些C++中join字符串的技巧。一、使用stringstreamstringstream是一个流。使用它可以将多个字符串连接起来,然后将它们转换为一个字符串。可......
  • 二进制CRUD
    二进制CRUD只适用于delphi客户端,不支持其他语言。多表查询procedureTForm1.btnClick(Sender:TObject);//多表查询beginvarbin:TBin;bin.resource:='bin';bin.dbid:='1';bin.sqls:=['select*fromtgoods','select*fromtunit'......
  • 1.Elasticsearch集群包安装、二进制安装与Docker安装
    ElasticsearchElasticsearch是一个实时的全文搜索,存储库和分析引擎https://www.elastic.co/cn/what-is/elasticsearchElasticsearch在速度和可扩展性方面都表现出色,而且还能够索引多种类型的内容,可用于多种场景:应用程序搜索网站搜索企业搜索日志处理和分析基础设施指标和......
  • 异或运算的一点规律
    亦或就是相同为0,不同为1若AxorB==C则:1、A xorC==BC xorA==BB xorA==CAxorB==CCxorB==ABxorC==A(满足类似于交换律的东西)2、(AxorB)xorC==0AxorBxorC==0(AxorC)xorB==0AxorCxorB==0(CxorB)xorA==0C xor B xorA==0 ......
  • XL-Formula流式统计运算方式配置说明
    1、简介XL-Formula是一种用于描述流式统计运算方式的配置标准,它代表着一种通用型流式统计系统的实现方法,更深层次它代表着一种以通用型流式统计技术为切入点,低成本实现企业数据化运营的理念。该配置标准语法简洁、功能强大、解析效率高、便于理解和使用。XL-Formula涵盖了各种......
  • JavaSE--运算符
    一、运算符运算符:用于指明对于操作数的运算方式1、运算符分类  1)按照操作数的数目分  单目操作符、双目操作符、三目操作符  2)按照运算符的功能来分  算术运算符、赋值运算符、关系运算符、逻辑运算符2、运算符详解  1)算数运算符+加法-减法*乘法/除法......
  • Tensor - 简介、创建、操作与运算
    一、简介1.1Variable和Tensor的关系Variable是torch.autograd中的数据类型,用于封装Tensor,使其可以进行自动求导。0.4.0后Variable并入了Tensor。#Variable含有的属性datagradgrad_fnrequires_gradis_leaf#Tensor新增的三个属性dtype#9种,包含float、int、bool......
  • 数据挖掘(五) -----基于Spark的可伸缩基因数据分析平台开源存储运算架构hail全面了解
    hail简介hail是一个开源的、通用的、面向python数据类型的处理基因数据专用的分析库和方法解决方案。hail的存在是为了支持多维度的复杂的数据结构,比如全基因组关联数据研究(GWAS).GWASTutorialhail的底层是通过python,scala,java和apachespark来实现的。hail官网gitlab官方文......
  • C++ | 运算符重载
    运算符重载在类中的函数进行重载(成员函数)运算符重载用于重新定义运算符的作用,使用函数名称operatorOP作为函数名,其中OP为具体的运算符(如operator+)classTime{Timeoperator+(constTime&t);};Timea,b;Timec=a+b;在成员函数中重载的运算符,如+-等,默认左边......