C#位运算实际作用之操作整型某一位

1.前言

前几天写了两篇关于c#位运算的文章
c#位运算基本概念与计算过程
C#位运算实际运用
在文中也提到了位运算的实际作用之一就是合并整型,当时引用了一个问题:
C# 用两个short,一个int32拼成一个long型,高16位用short,中间32位用int,最低16位用另外一个short。
答案如下:
高16位shortA、中间32位intA、低16位shortB

longResult=((long)shortA << 48 )+ ((long)intA << 16)+ shortB

根据longResult获取前16位shortA,中间32位intA,后16位shortB

    shortA=(short)(longResult>>48)
intA=(int)((longResult>>16)&0xFFFFFFFF)
shortB=(short)(longResult&0xFFFF)

评论者pushouli、czd890 评论到,合并这个long类型的结果是使用加法计算,可以使用位逻辑或运算,想了想确实使用| 位逻辑或运算也是可以解决问题的,能够实现相互转换。

@ pushouli 用+ 和 | 在这里性能上应该没有太大区别。 但是感觉用 | 更能表达意思一些

longResult=(((long)shortA << 48) |((long)intA << 16)) | (long)shortB

1|0=1、1|1=1、0|0=0

其计算结果longResult是一样的,运算方式不一样,其计算过程可以看看前面写的一篇
C#位运算实际运用
如图:
640?wx_fmt=png
这篇文章就将记录两个知识点:
1.负数的二进制位表示法
2.位运算如何直接操作Int类型某一位

2.负数的二进制位表示法

原码:一个整数按照绝对值的大小转换成的二进制数,称为原码
一个short 16位的整数9的原码是:

0000    0000    0000    1001

反码:一个二进制数按位取反,所得的二进制数成为原二进制数的反码
取9的二进制数的反码,可以使用位逻辑非运算 ~
取反后的16位二进制

1111    1111    1111    0110

补码:反码加1称为补码,简而言之,要得到一个属的补码,先得到这个数的反码,然后再将反码加上1,所得数称为补码
那么9的补码也就是

1111    1111    1111    0110

加上1的结果,如下:

1111    1111    1111    0111

即-9的16位二进制表示是

1111    1111    1111    0111

如图:
640?wx_fmt=png

3.c#Int有符号的和无符号的区别

话不多说,直接明确三点结论:
1.实际开发中,都用的是有符号的Int(应该默认强制要求),只有整型有有无符号的特征,Double、Decimal,是没有这种特征的。
2.无符号数中,所有的位都用于直接表示该值的大小。
3.有符号数中,最高位用于表示正负。
这里还是简单地啰嗦几句关于有符号和无符号的区别,UInt32和Int32的区别
这里说的Int指的是32位有符号的类型
Int32的值范围是 -2147483648 至2147483647,也就是
-2的31次方到2的31次方-1
符号位表示的意义就在于此,最前面的位表示正负。

-2148483648的32位二进制是:

1000    0000    0000    0000    0000    0000    0000    0000

2147483647的32位二进制是:

0111    1111    1111    1111    1111    1111    1111    1111

那么c#中UInt32的最大值是什么呢?
UInt32的范围是0到2的32次方4294967295,最大值32位二进制是

1111    1111    1111    1111    1111    1111    1111    1111

所以得出结论无符号只能表示正数,有符号可以表示正负数。
如图:
640?wx_fmt=png

4.c#Int如何直接操作每一位

前面已经说到,Int表示的是有符号的,最高位表示的正负,一个Int有32位,虽然我们可以直接操作这32位,但是如果直接操作明显会改变数据类型的正负、最大范围。
这里写了一个泛型的示例,操作整型(int、short、long)的每一位。

           
public static IEnumerable<bool> GetIntOfBitList<T>(T intVal)
{
Type intType = intVal.GetType();
byte bitlength = 0;
if (intType == typeof(Int32))
bitlength = 32;
else if (intType == typeof(Int16))
bitlength = 16;
else if (intType == typeof(Int64))
bitlength = 64;
else
throw new ArgumentException("必须是整型");

object intOject = (object)intVal;
var resultList = new List<bool>(bitlength);
for (var i = 0; i < bitlength; i++)
{
var temoIntBit = 1 << i;
if (intType == typeof(Int32))
resultList.Add((((Int32)intOject) & temoIntBit) == temoIntBit);
if (intType == typeof(Int16))
resultList.Add((((Int16)intOject) & temoIntBit) == temoIntBit);
if (intType == typeof(Int64))
resultList.Add((((Int64)intOject) & temoIntBit) == temoIntBit);
}
return resultList;
}

public static bool GetBitValue<T>(T intVal,byte index)
{
Type intType = intVal.GetType();
byte bitlength = 0;
if (intType == typeof(Int32))
bitlength = 32;
else if (intType == typeof(Int16))
bitlength = 16;
else if (intType == typeof(Int64))
bitlength = 64;
else
throw new ArgumentException("必须是整型");

if (index > bitlength-1 || index < 1)
throw new ArgumentOutOfRangeException("index");

object intOject = (object)intVal;
var tempBit = 1 << index;

if (intType == typeof(Int32))
return (((int)intOject) & tempBit) == tempBit;
else if (intType == typeof(Int16))
return (((Int16)intOject) & tempBit) == tempBit;
else
return (((Int64)intOject) & tempBit) == tempBit;
}

public static T SetBitValue<T>(T intVal,byte index,bool bitValue)
{
Type intType = intVal.GetType();
byte bitlength = 0;
if (intType == typeof(Int32))
bitlength = 32;
else if (intType == typeof(Int16))
bitlength = 16;
else if (intType == typeof(Int64))
bitlength = 64;
else
throw new ArgumentException("必须是整型");

if (index >= bitlength-1 || index < 1)
throw new ArgumentOutOfRangeException("index");

object intOject = (object)intVal;
var tempBit = 1 << index;

if (intType == typeof(Int32))
{
int tempInt = (int)intOject;
return (T)((bitValue ? (tempInt | tempBit) : (tempInt & ~tempBit)) as Object);
}
else if (intType == typeof(Int16))
{
Int16 tempInt = (Int16)intOject;
return (T)((bitValue ? (tempInt | tempBit) : (tempInt & ~tempBit)) as Object);
}
else
{
Int64 tempInt = (Int64)intOject;
return (T)((bitValue ? (tempInt | tempBit) : (tempInt & ~tempBit)) as Object);
}
}

测试截图:
640?wx_fmt=png
思考:这个方法能操作负数吗?

原文地址:https://www.cnblogs.com/zhangmumu/p/10805312.html

.NET社区新闻,深度好文,欢迎访问公众号文章汇总 http://www.csharpkit.com 
640?wx_fmt=jpeg

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/316054.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

CF1458B Glass Half Spilled

CF1458B Glass Half Spilled 题意&#xff1a; 有n杯水&#xff0c;第i杯有容积aia_{i}ai​单位&#xff0c;初始时装有bib_{i}bi​单位的水 现在你可以进行若干次操作,每次选择一杯水的一定水量并倒到另一杯水中,但是因为这些杯子形状非常奇怪,因此每倒一次水,倒的水会有一半…

2019 微软Build大会预告:值得开发者期待的是哪些?

北京时间 5 月 2 日上午 10:00&#xff08;太平洋时间 5 月 1 日晚 19:00&#xff09;&#xff0c;微软通信部门副总裁 Frank Shaw 通过网络提前预告了即将于两天后在美国西雅图召开的 2019 年微软 Build 大会的重点发布与相关信息。InfoQ 记者对本次提前发布做了简要摘录&…

线性时间选择--用于解决第k大(小)元素问题(未补)

线性时间选择–用于解决第k大(小)元素问题

使用高性能Pipelines构建.NET通讯程序

.NET Standard支持一组新的API&#xff0c;System.Span, System.Memory&#xff0c;还有System.IO.Pipelines。这几个新的API极大了提升了.NET程序的效能&#xff0c;将来.NET很多基础API都会使用它们进行重写。Pipelines旨在解决.NET编写Socket通信程序时的很多困难&#xff0…

全球开发者的年度盛宴:微软全球开发者大会 Build 2019邀您一同加入

一年一度的微软全球开发者大会&#xff08;Build&#xff09;将于5月6日至8日在美国西雅图举办。本届大会将围绕全球当下的热门技术展开&#xff0c;包括人工智能、机器学习、容器、DevOps、物联网、混合现实以及Power Platforms等&#xff1b;微软热爱开发者、重视开发者&…

Codeforces Round #688 (Div. 2)

Codeforces Round #688 (Div. 2) 题号题目知识点-ACancel the Trains签到(题解)BSuffix Operations思维CTriangles思维(略)DCheckpointsEDog SnacksFEven Harder

Oracle杀死Java EE:名正言顺转到.NET Core

Eclipse 基金会执行董事 Mike Milinkovich 昨日在博客发表了 Oracle 与 Eclipse 基金会之间关于 Java 商标谈判的结果 —— 双方的谈判最后以失败告终&#xff0c;Oracle 拒绝出让 Java 商标。Mike 在博客中还提及了 Eclipse 基金会和 Oracle 之间关于 Jakarta EE 的协议、Java…

cf1453B. Suffix Operations

cf1453B. Suffix Operations 题意&#xff1a; 给你一个整数序列&#xff0c;其中有n个元素。你需要对这个序列进行操作。 1 在所有操作开始前&#xff0c;你可以选择一个数&#xff0c;并修改他的值&#xff0c;这个值你可以自己定。本操作无花费。 2 选择一个下标i&#…

程序员修神之路--redis做分布式锁可能不那么简单

点击上方“蓝字”带你去看小星星菜菜哥&#xff0c;复联四上映了&#xff0c;要不要一起去看看&#xff1f;又想骗我电影票&#xff0c;对不对&#xff1f;呵呵&#xff0c;想去看了叫我呀看来你工作不饱和呀哪有&#xff0c;这两天我刚基于redis写了一个分布式锁&#xff0c;很…

CF1548A Web of Lies

CF1548A Web of Lies 题意&#xff1a; 题解&#xff1a; 第一感觉是先建边然后跑dfs&#xff0c;但是看数据范围肯定不对&#xff0c;现在我们开始考虑其中的性质 对于第三个操作&#xff0c;我们是要将所有>2的连通块进行判断的&#xff0c;我们考虑对于编号为x的点&…

Abp CLI 上线

Abp vNext CLI 工具随着0.17.0版本的发布已经上线.Abp中文网第一时间制作 Cn.Abp.Cli 工具. 目前提供下载加速, 后续Abp中文网CLI将会提供更多本土化功能, 并随时与官方CLI代码同步.源码(查看原文): https://github.com/cnAbp/abp-cli原文地址&#xff1a;https://mp.weixin.qq…

如何正确地生成一个随机数

参考文章 笔记 | 如何正确地生成一个随机数 CF曾提到&#xff1a;Don’t use rand(): a guide to random number generators in C 文章总结&#xff1a; 1 .rand()的随机范围太小了&#xff0c;在某些平台下&#xff08;例如 Windows&#xff09;RAND_MAX 只有 32768。如果需要…

一篇短文带您了解一下EasyCaching

前言从2017年11月11号在Github创建EasyCaching这个仓库&#xff0c;到现在也已经将近一年半的时间了&#xff0c;基本都是在下班之后和假期在完善这个项目。由于EasyCaching目前只有英文的文档托管在Read the Docs上面&#xff0c;当初选的MkDocs现在还不支持多语言&#xff0c…

[开源]OSharpNS - .net core 快速开发框架 - 简介

OSharpNS全称OSharp Framework with .NetStandard2.0&#xff0c;是一个基于.NetStandard2.0开发的一个.NetCore快速开发框架。这个框架使用最新稳定版的.NetCore SDK&#xff08;当前是.NET Core 2.2&#xff09;&#xff0c;对 AspNetCore 的配置、依赖注入、日志、缓存、实体…

Ozon Tech Challenge 2020 (Div.1 + Div.2, Rated, T-shirts + prizes!)

Ozon Tech Challenge 2020 (Div.1 Div.2, Rated, T-shirts prizes!) 题号题目知识点AKuroni and the GiftsBKuroni and Simple StringsCKuroni and Impossible CalculationDKuroni and the Celebration思维EKuroni and the Score Distribution构造FKuroni and the Punishmen…

Web 版 VS Code (Visual Studio Online) 即将来临!

今天&#xff08;北京时间 2019 年 5 月 7 日&#xff09;&#xff0c;在微软Build 2019开发者大会上&#xff0c;微软宣布了 Web 版本的 VS Code - Visual Studio Online。相信读者们对Web 版 VS Code 期待已久了。对 VS Code 熟悉的朋友应该知道&#xff0c;VS Code 是基于 E…

CF1305D Kuroni and the Celebration

CF1305D Kuroni and the Celebration 题意&#xff1a; 给你一棵有 n 个节点的树。对于每次询问&#xff0c;提交两个点&#xff0c;评测机会返回这两个点的 LCA。求树根。 询问格式为 ? u v&#xff0c;此时评测机会返回 u 和 v 的 LCA。 提交格式为 ! x&#xff0c;表示…

CF1305F Kuroni and the Punishment

CF1305F Kuroni and the Punishment 题意&#xff1a; 给定 n 个数。每次可以选择将一个数 1 或 -1 。求至少多少次操作使得整个序列都是正数且全部元素的 gcd>1 。 n<2e5,ai<1012n<2e5,a_{i}<10^{12}n<2e5,ai​<1012 题解&#xff1a; 首先不难想到&…

2019年了,C#发展的怎么样了呢?

C# 8.0我估计大多数程序员对于C# 5.0之后的改进都没有什么太多的认知&#xff0c;的确从C# 5.0开始C#已经没什么太多东西可以从其他语言借鉴&#xff0c;Anders的重心也开始逐步倾斜到TypeScript&#xff0c;所以从5.0引入async之后C#语言发展速度开始减缓了。C#6引入了大量的语…

微软宣布新命令行工具 Windows Terminal 和 WSL2

微软在 Build 2019 已经宣布推出名为Windows Terminal的新款命令行工具 , 这款工具可以访问多种环境的中心位置。例如可以直接访问PowerShell、CMD.EXE、Windows Linux子系统等等&#xff0c;开发者使用此工具可以简化工作。这款新工具支持多选项卡同时连接多个环境或服务器&a…