2016-09-08 16 views
0

的右側我有一些位和一些斷例如UINT64值:移位比特集合在一個UINT64到它們各自的字節

01010101 01010101 01010101 01010101 01010101 01010101 01010101 01010101 

如何可以容易地將組位向右移動,如他們是各自字節如右端:

00001111 00001111 00001111 00001111 00001111 00001111 00001111 00001111 

我見過的,所有的方式移動的位到64位無符號整數正確的問題,但我只希望他們轉移到如果可能的話,它們所在的字節的權利。

謝謝。

+1

「easy」和「fast」之間有很大很大的區別。很難相信任何人都會找到容易接受的方法。創建一個映射所有可能字節值的查找字節[256]數組。 BitConverter.GetBytes + ToUInt64來使用它。簡單而快速,它只需要鍵入數組初始值設定項即可。你的工作:) –

+0

這是否意味着靜態排列(特別是針對你所展示的模式)還是一般的SWAR綿羊和山羊操作? – harold

+0

理想情況下,這是一個普通的操作。 – Ward9250

回答

0
using System; 
using System.Linq; 

namespace ConsoleApplication5 
{ 
    public class Program 
    { 
    public static void Main(String[] args) 
    { 
     var inputAsBinaryString = "01010101 01010101 01010101 01010101 01010101 01010101 01010101 01010101"; 
     var inputAsUInt64 = GetBinaryStringAsUInt64(inputAsBinaryString); 

     var actualAsUInt64 = GetRightAlignedBytes(inputAsUInt64); 
     var actualAsBinaryString = GetAsBinaryString(actualAsUInt64); 

     var expectedAsBinaryString = "00001111 00001111 00001111 00001111 00001111 00001111 00001111 00001111"; 
     var expectedAsUInt64 = GetBinaryStringAsUInt64(expectedAsBinaryString); 
    } // <-- Set a breakpoint here and inspect the values. 

    /* Bit-manipulation methods. */ 

    private static UInt64 GetRightAlignedBytes(UInt64 n) 
    { 
     var rightAlignedByteArray = 
     BitConverter 
     .GetBytes(n) 
     .Select(b => GetRightAlignedByte(b)) 
     .ToArray(); 
     return BitConverter.ToUInt64(rightAlignedByteArray, 0); 
    } 

    /* Shove all of a byte's bits to the right. */ 
    private static Byte GetRightAlignedByte(Byte b) 
    { 
     /* The << operator only works on 32 and 64 bit values. 
     This requires treating the result as an Int32 until it's returned. */ 
     Int32 result = 0; 
     var numberOfSetBits = GetNumberOfSetBits(b); 

     for (Byte n = 1; n <= numberOfSetBits; n++) 
     { 
     /* Need to set n bits, but only perform n - 1 left shifts. */ 

     result |= 1; 

     if (n < numberOfSetBits) 
      result = result << 1; 
     } 

     return (Byte) result; 
    } 

    private static Byte GetNumberOfSetBits(Byte b) 
    { 
     /* There are many ways to count the number of "set" bits in a byte. 

     This StackOverflow question 

      http://stackoverflow.com/questions/109023/how-to-count-the-number-of-set-bits-in-a-32-bit-integer 

     has a mind-numbing collection of answers. 
     Most of them are probably more efficient than this method. */ 

     Int32 result = 0; 

     /* The >> operator only works on 32 and 64 bit values. 
     This requires converting the Byte parameter "b" to an Int32. */ 
     Int32 n = b; 

     while (n > 0) 
     { 
     result += (n & 1); 
     n = n >> 1; 
     } 

     return (Byte) result; 
    } 

    /* GetBinaryStringAs* methods */ 

    private static Int32 GetBinaryStringAsInt32(String s) 
    { 
     return Convert.ToInt32(String.Join("", s.Trim().Where(c => (c == '0') || (c == '1'))), 2); 
    } 

    private static UInt64 GetBinaryStringAsUInt64(String s) 
    { 
     return Convert.ToUInt64(String.Join("", s.Trim().Where(c => (c == '0') || (c == '1'))), 2); 
    } 

    /* GetAsBinaryString methods. */ 

    private static String GetAsBinaryString_Helper(Byte[] bytes) 
    { 
     /* The order of the bytes returned by System.BitConverter.GetBytes() 
     depends on the CPU architecture. The returned byte array 
     will round-trip with other BitConverter methods, like its 
     ToInt32() method. But those same bytes will not round-trip 
     with any of the System.Convert methods, like ToInt32(String, Int32). 

     The System.Convert.To* methods expect the order of the bytes they 
     receive to be the *reverse* of the order returned by 
     System.BitConverter.GetBytes(). 

     The value returned by this method can - after stripping off the spaces - 
     be fed into a System.Convert.To*() method. 

     For example, this round-trip test should print "True": 

         // Hi byte     Lo byte 
      Int32 n = 257; // 00000000 00000000 00000001 00000001 
      Console.WriteLine(GetBinaryStringAsInt32(GetAsBinaryString(n)) == n); 

     */ 

     return String.Join(" ", bytes.Reverse().Select(b => GetAsBinaryString(b))); 
    } 

    private static String GetAsBinaryString(Int32 n) 
    { 
     /* Note that signed integers use two's complement 
     binary representation for negative numbers. 

     For example, calling this method with a parameter 
     of -42 returns this string: 

      11111111 11111111 11111111 11010110 

     */ 
     return GetAsBinaryString_Helper(BitConverter.GetBytes(n)); 
    } 

    private static String GetAsBinaryString(UInt64 n) 
    { 
     return GetAsBinaryString_Helper(BitConverter.GetBytes(n)); 
    } 

    private static String GetAsBinaryString(Byte n) 
    { 
     return Convert.ToString(n, 2).PadLeft(8, '0'); 
    } 
    } 
} 
相關問題