C# Tips:位运算相关

共享一堆位操作相关的方法:


// -----------------------------------------------------------------------
// <copyright file="UInt64MaskHelper.cs" author="Yaping Xin">
//
//
//  File Name           : UInt64MaskHelper.cs
//  Description         : Helper class to support UInt64 bit mask.
//  Project Title       : UInt64MaskHelper
//  Author(s)           : Yaping Xin
//  Code Review Done    :
//  Modification History: Created at Aug 10, 2012
//
// </copyright>
// -----------------------------------------------------------------------
namespace BitsHelper
{
    /// <summary>
    /// Helper class to support UInt64 bit mask.
    /// </summary>
    public static class UInt64MaskHelper
    {
        #region Constant definition
        /// <summary>
        /// Constant definition of max avaiable bytes length.
        /// </summary>
        public const int MaxBytesLength = 8;

        /// <summary>
        /// Constant definition bits count within a byte
        /// </summary>
        public const int ByteBitsCount = 8;
        #endregion Constant definition

        #region Useful Bytes/Bits static readonly array definition
        /// <summary>
        /// Array of UInt64 byte mask values.
        /// </summary>
        private static readonly ulong[] U64ByteMaskValues = new ulong[]
        {
            0x00000000000000FF, 
            0x000000000000FF00, 
            0x0000000000FF0000, 
            0x00000000FF000000, 
            0x000000FF00000000, 
            0x0000FF0000000000, 
            0x00FF000000000000, 
            0xFF00000000000000
        };

        /// <summary>
        /// Array of max values storaged in different amount of bytes within UInt64 scope. 
        /// </summary>
        private static readonly ulong[] U64BytesMaxValues = new ulong[]
        {
            0x00000000000000FF,
            0x000000000000FFFF,
            0x0000000000FFFFFF,
            0x00000000FFFFFFFF,
            0x000000FFFFFFFFFF,
            0x0000FFFFFFFFFFFF,
            0x00FFFFFFFFFFFFFF,
            0xFFFFFFFFFFFFFFFF
        };

        /// <summary>
        /// Array of shift values to specific byte lowest bit position.
        /// </summary>
        private static readonly byte[] BytePositionShiftValues = new byte[]
        {
            0, 8, 16, 24, 32, 40, 48, 56
        };

        /// <summary>
        /// Array of byte bit mask values.
        /// </summary>
        private static readonly byte[] ByteBitMaskValues = new byte[]
        {
            0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80
        };

        /// <summary>
        /// Array of byte bit mask values.
        /// </summary>
        private static readonly byte[] ByteBitOffMaskValues = new byte[]
        {
            0xFE, 0xFD, 0xFB, 0xF7, 0xEF, 0xDF, 0xBF, 0x7F
        };
        #endregion Useful Bytes/Bits static readonly array definition

        #region Enumeration definition
        /// <summary>
        /// Enumeration definition of the error code
        /// </summary>
        public enum ErrorCode : uint
        {
            /// <summary>No error occurs</summary>
            OK = 0,

            /// <summary>Argument is Null</summary>
            ArgumentIsNull = 1,

            /// <summary>Argument is out of range</summary>
            ArgumentOutOfRange = 2,
        }
        #endregion Enumeration definition

        #region Encoding methods (numeric value to bytes/bits)
        /// <summary>
        /// Gets the bytes array to storage the specific UInt64 value.
        /// </summary>
        /// <param name="value">The specific UInt64 value.</param>
        /// <returns>The bytes array.</returns>
        public static byte[] GetBytes(ulong value)
        {
            byte[] result = new byte[MaxBytesLength];

            ulong maskResult = value & U64ByteMaskValues[0];
            result[0] = (byte)maskResult;

            for (int i = 1; i < MaxBytesLength; i++)
            {
                maskResult = value & U64ByteMaskValues[i];
                result[i] = (byte)(maskResult >> BytePositionShiftValues[i]);
            }

            return result;
        }

        /// <summary>
        /// Gets the byte at specific position from the UInt64 value.
        /// Notes: this function will not return detailed error code while error occurs.
        /// </summary>
        /// <param name="value">The UInt64 value.</param>
        /// <param name="bytePosition">The byte position.</param>
        /// <param name="result">The byte to get.</param>
        /// <returns>
        ///   <c>true</c> indicates no error occurs during calculating; 
        ///   <c>fasle</c> indicates error occurs.
        /// </returns>
        public static bool GetByte(ulong value, int bytePosition, out byte result)
        {
            ErrorCode errorCode;
            return UInt64MaskHelper.GetByte(value, bytePosition, out result, out errorCode);
        }

        /// <summary>
        /// Gets the byte at specific position from the UInt64 value.
        /// </summary>
        /// <param name="value">The UInt64 value.</param>
        /// <param name="bytePosition">The byte position.</param>
        /// <param name="result">The byte to get.</param>
        /// <param name="errorCode">The error code.
        /// Will be set to ErrorCode.OK if no error occurs.</param>
        /// <returns>
        ///   <c>true</c> indicates no error occurs during calculating; 
        ///   <c>fasle</c> indicates error occurs, and detailed error is wrote in errorCode output parameter.
        /// </returns>
        public static bool GetByte(
            ulong value,
            int bytePosition,
            out byte result,
            out ErrorCode errorCode)
        {
            if (bytePosition < 0 || bytePosition >= MaxBytesLength)
            {
                result = 0;
                errorCode = ErrorCode.ArgumentOutOfRange;
                return false;
            }

            ulong maskResult;

            if (bytePosition == 0)
            {
                maskResult = value & U64ByteMaskValues[0];

                goto EXIT_PASS;
            }

            maskResult = value & U64ByteMaskValues[bytePosition];
            maskResult >>= BytePositionShiftValues[bytePosition];

        EXIT_PASS:
            result = (byte)maskResult;
            errorCode = ErrorCode.OK;
            return true;
        }

        /// <summary>
        /// Gets the bit at specific position from the byte value.
        /// Notes: this function will not return detailed error code while error occurs.
        /// </summary>
        /// <param name="value">The byte value.</param>
        /// <param name="bitPosition">The bit position.</param>
        /// <param name="result">The bit (0 or 1) to get.</param>
        /// <returns>
        ///   <c>true</c> indicates no error occurs during calculating; 
        ///   <c>fasle</c> indicates error occurs.
        /// </returns>
        public static bool GetBit(byte value, int bitPosition, out byte result)
        {
            ErrorCode errorCode;
            return UInt64MaskHelper.GetBit(value, bitPosition, out result, out errorCode);
        }

        /// <summary>
        /// Gets the bit at specific position from the byte value.
        /// </summary>
        /// <param name="value">The byte value.</param>
        /// <param name="bitPosition">The bit position.</param>
        /// <param name="result">The bit (0 or 1) to get.</param>
        /// <param name="errorCode">The error code.
        /// Will be set to ErrorCode.OK if no error occurs.</param>
        /// <returns>
        ///   <c>true</c> indicates no error occurs during calculating; 
        ///   <c>fasle</c> indicates error occurs, and detailed error is wrote in errorCode output parameter.
        /// </returns>
        public static bool GetBit(
            byte value,
            int bitPosition,
            out byte result,
            out ErrorCode errorCode)
        {
            if (bitPosition < 0 || bitPosition >= ByteBitsCount)
            {
                result = 0;
                errorCode = ErrorCode.ArgumentOutOfRange;
                return false;
            }

            if (bitPosition == 0)
            {
                result = (byte)(value & ByteBitMaskValues[0]);
                errorCode = ErrorCode.OK;
                return true;
            }

            byte maskResult = (byte)(value & ByteBitMaskValues[bitPosition]);
            result = maskResult >>= bitPosition;
            errorCode = ErrorCode.OK;
            return true;
        }
        #endregion Encoding methods (numeric value to bytes/bits)

        #region Decoding methods (bytes/bits to numeric value)
        /// <summary>
        /// Gets the UInt64 value from bytes array.
        /// Notes: this function will not return detailed error code while error occurs.
        /// </summary>
        /// <param name="bytes">The bytes array.</param>
        /// <param name="value">The UInt64 value.</param>
        /// <returns>
        ///   <c>true</c> indicates no error occurs during calculating; 
        ///   <c>fasle</c> indicates error occurs.
        /// </returns>
        public static bool GetUInt64(byte[] bytes, out ulong value)
        {
            ErrorCode errorCode;
            return UInt64MaskHelper.GetUInt64(bytes, out value, out errorCode);
        }

        /// <summary>
        /// Gets the UInt64 value from bytes array.
        /// </summary>
        /// <param name="bytes">The bytes array.</param>
        /// <param name="value">The UInt64 value.</param>
        /// <param name="errorCode">The error code.
        /// Will be set to ErrorCode.OK if no error occurs.</param>
        /// <returns>
        ///   <c>true</c> indicates no error occurs during calculating; 
        ///   <c>fasle</c> indicates error occurs, and detailed error is wrote in errorCode output parameter.
        /// </returns>
        public static bool GetUInt64(byte[] bytes, out ulong value, out ErrorCode errorCode)
        {
            if (bytes == null || bytes.Length == 0)
            {
                errorCode = ErrorCode.ArgumentIsNull;
                value = 0;
                return false;
            }

            if (bytes.Length > MaxBytesLength)
            {
                errorCode = ErrorCode.ArgumentOutOfRange;
                value = 0;
                return false;
            }

            ulong result = bytes[0];
            ulong byteValue;

            if (bytes.Length > 1)
            {
                for (int i = 1; i < bytes.Length; i++)
                {
                    byteValue = bytes[i];
                    byteValue <<= BytePositionShiftValues[i];
                    result += byteValue;
                }
            }

            value = result;
            errorCode = ErrorCode.OK;
            return true;
        }
        #endregion Decoding methods (bytes/bits to numeric value)

        #region Set bit value
        /// <summary>
        /// Sets bit value at specific bit position within the raw byte.
        /// Notes: this function will not return detailed error code while error occurs.
        /// </summary>
        /// <param name="rawByte">The raw byte.</param>
        /// <param name="bitPosition">The bit position.</param>
        /// <param name="bitValue">if set to <c>true</c> [bit value].</param>
        /// <returns>
        ///   <c>true</c> indicates no error occurs during calculating; 
        ///   <c>fasle</c> indicates error occurs.
        /// </returns>
        public static bool SetBit(ref byte rawByte, int bitPosition, bool bitValue)
        {
            ErrorCode errorCode;
            return UInt64MaskHelper.SetBit(ref rawByte, bitPosition, bitValue, out errorCode);
        }

        /// <summary>
        /// Sets bit value at specific bit position within the raw byte.
        /// </summary>
        /// <param name="rawByte">The raw byte.</param>
        /// <param name="bitPosition">The bit position.</param>
        /// <param name="bitValue"><c>true</c> indicates set bit value to 1; 
        /// otherwise set bit value to 0.</param>
        /// <param name="errorCode">The error code.
        /// Will be set to ErrorCode.OK if no error occurs.</param>
        /// <returns>
        ///   <c>true</c> indicates no error occurs during calculating; 
        ///   <c>fasle</c> indicates error occurs, and detailed error is wrote in errorCode output parameter.
        /// </returns>
        public static bool SetBit(ref byte rawByte, int bitPosition, bool bitValue, out ErrorCode errorCode)
        {
            if (bitPosition < 0 || bitPosition >= ByteBitsCount)
            {
                errorCode = ErrorCode.ArgumentOutOfRange;
                return false;
            }

            if (bitValue)
            {
                rawByte |= ByteBitMaskValues[bitPosition];
            }
            else
            {
                rawByte &= ByteBitOffMaskValues[bitPosition];
            }

            errorCode = ErrorCode.OK;
            return true;
        }
        #endregion Set bit value
    }
}



你可能感兴趣的:(function,C#,byte,encoding,output,methods)