生活随笔
收集整理的這篇文章主要介紹了
C#位运算实际作用之操作整型某一位
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
1.前言
前幾天寫(xiě)了兩篇關(guān)于c#位運(yùn)算的文章
c#位運(yùn)算基本概念與計(jì)算過(guò)程
C#位運(yùn)算實(shí)際運(yùn)用
在文中也提到了位運(yùn)算的實(shí)際作用之一就是合并整型,當(dāng)時(shí)引用了一個(gè)問(wèn)題:
C# 用兩個(gè)short,一個(gè)int32拼成一個(gè)long型,高16位用short,中間32位用int,最低16位用另外一個(gè)short。
答案如下:
高16位shortA、中間32位intA、低16位shortB
longResult=((long)shortA << 48 )+ ((long)intA << 16)+ shortB
根據(jù)longResult獲取前16位shortA,中間32位intA,后16位shortB
shortA=(short)(longResult>>48)intA=(int)((longResult>>16)&0xFFFFFFFF)shortB=(short)(longResult&0xFFFF)
評(píng)論者pushouli、czd890 評(píng)論到,合并這個(gè)long類型的結(jié)果是使用加法計(jì)算,可以使用位邏輯或運(yùn)算,想了想確實(shí)使用| 位邏輯或運(yùn)算也是可以解決問(wèn)題的,能夠?qū)崿F(xiàn)相互轉(zhuǎn)換。
1樓 2019-04-30 07:28 pushouli 簡(jiǎn)單明了,但感覺(jué)合并那里,不應(yīng)該用加法去算,用|運(yùn)算符更合適。
11樓 2019-04-30 18:10 czd890
@ pushouli 用+ 和 | 在這里性能上應(yīng)該沒(méi)有太大區(qū)別。 但是感覺(jué)用 | 更能表達(dá)意思一些
longResult=(((long)shortA << 48) |((long)intA << 16)) | (long)shortB
1|0=1、1|1=1、0|0=0
其計(jì)算結(jié)果longResult是一樣的,運(yùn)算方式不一樣,其計(jì)算過(guò)程可以看看前面寫(xiě)的一篇
C#位運(yùn)算實(shí)際運(yùn)用
如圖:
這篇文章就將記錄兩個(gè)知識(shí)點(diǎn):
1.負(fù)數(shù)的二進(jìn)制位表示法
2.位運(yùn)算如何直接操作Int類型某一位
2.負(fù)數(shù)的二進(jìn)制位表示法
原碼:一個(gè)整數(shù)按照絕對(duì)值的大小轉(zhuǎn)換成的二進(jìn)制數(shù),稱為原碼
一個(gè)short 16位的整數(shù)9的原碼是:
0000 0000 0000 1001
反碼:一個(gè)二進(jìn)制數(shù)按位取反,所得的二進(jìn)制數(shù)成為原二進(jìn)制數(shù)的反碼
取9的二進(jìn)制數(shù)的反碼,可以使用位邏輯非運(yùn)算 ~
取反后的16位二進(jìn)制
1111 1111 1111 0110
補(bǔ)碼:反碼加1稱為補(bǔ)碼,簡(jiǎn)而言之,要得到一個(gè)屬的補(bǔ)碼,先得到這個(gè)數(shù)的反碼,然后再將反碼加上1,所得數(shù)稱為補(bǔ)碼
那么9的補(bǔ)碼也就是
1111 1111 1111 0110
加上1的結(jié)果,如下:
1111 1111 1111 0111
即-9的16位二進(jìn)制表示是
1111 1111 1111 0111
如圖:
3.c#Int有符號(hào)的和無(wú)符號(hào)的區(qū)別
話不多說(shuō),直接明確三點(diǎn)結(jié)論:
1.實(shí)際開(kāi)發(fā)中,都用的是有符號(hào)的Int(應(yīng)該默認(rèn)強(qiáng)制要求),只有整型有有無(wú)符號(hào)的特征,Double、Decimal,是沒(méi)有這種特征的。
2.無(wú)符號(hào)數(shù)中,所有的位都用于直接表示該值的大小。
3.有符號(hào)數(shù)中,最高位用于表示正負(fù)。
這里還是簡(jiǎn)單地啰嗦幾句關(guān)于有符號(hào)和無(wú)符號(hào)的區(qū)別,UInt32和Int32的區(qū)別
這里說(shuō)的Int指的是32位有符號(hào)的類型
Int32的值范圍是 -2147483648 至2147483647,也就是
-2的31次方到2的31次方-1
符號(hào)位表示的意義就在于此,最前面的位表示正負(fù)。
-2148483648的32位二進(jìn)制是:
1000 0000 0000 0000 0000 0000 0000 0000
2147483647的32位二進(jìn)制是:
0111 1111 1111 1111 1111 1111 1111 1111
那么c#中UInt32的最大值是什么呢?
UInt32的范圍是0到2的32次方4294967295,最大值32位二進(jìn)制是
1111 1111 1111 1111 1111 1111 1111 1111
所以得出結(jié)論無(wú)符號(hào)只能表示正數(shù),有符號(hào)可以表示正負(fù)數(shù)。
如圖:
4.c#Int如何直接操作每一位
前面已經(jīng)說(shuō)到,Int表示的是有符號(hào)的,最高位表示的正負(fù),一個(gè)Int有32位,雖然我們可以直接操作這32位,但是如果直接操作明顯會(huì)改變數(shù)據(jù)類型的正負(fù)、最大范圍。
這里寫(xiě)了一個(gè)泛型的示例,操作整型(int、short、long)的每一位。
/// <summary>/// Int16\Int32\Int64類型/// </summary>/// <returns>true 1\false 0的集合</returns>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;elsethrow 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;}/// <summary>/// 獲取T整型中某一位的值/// </summary>/// <typeparam name="T">泛型類型包括int\short\long</typeparam>/// <param name="intVal">int\short\long</param>/// <param name="index">從右到左0-T的總位數(shù)</param>/// <returns>true:1\false:0</returns>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;elsethrow 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;elsereturn (((Int64)intOject) & tempBit) == tempBit;}/// <summary>/// 設(shè)置整型數(shù)據(jù)中某一位的值/// </summary>/// <typeparam name="T">int\short\long</typeparam>/// <param name="intVal">設(shè)置前的值</param>/// <param name="index">從右到左0-T的總位數(shù)</param>/// <param name="bitValue">需要設(shè)置的值 true:1\false:0</param>/// <returns>設(shè)置位值后新的整型</returns>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;elsethrow new ArgumentException("必須是整型");//不能去設(shè)置最高位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);}}
測(cè)試截圖:
思考:這個(gè)方法能操作負(fù)數(shù)嗎?
轉(zhuǎn)載于:https://www.cnblogs.com/zhangmumu/p/10805312.html
《新程序員》:云原生和全面數(shù)字化實(shí)踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀
總結(jié)
以上是生活随笔為你收集整理的C#位运算实际作用之操作整型某一位的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。