//****************************************************************************************************** // UInt24.cs - Gbtc // // Copyright © 2010, Grid Protection Alliance. All Rights Reserved. // // Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See // the NOTICE file distributed with this work for additional information regarding copyright ownership. // The GPA licenses this file to you under the Eclipse Public License -v 1.0 (the "License"); you may // not use this file except in compliance with the License. You may obtain a copy of the License at: // // http://www.opensource.org/licenses/eclipse-1.0.php // // Unless agreed to in writing, the subject software distributed under the License is distributed on an // "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the // License for the specific language governing permissions and limitations. // // Code Modification History: // ---------------------------------------------------------------------------------------------------- // 11/12/2004 - J. Ritchie Carroll // Initial version of source generated. // 08/4/2009 - Josh L. Patterson // Edited Code Comments. // 09/14/2009 - Stephen C. Wills // Added new header and license agreement. // 10/8/2012 - Danyelle Gilliam // Modified Header // //****************************************************************************************************** #region [ Contributor License Agreements ] /**************************************************************************\ Copyright © 2009 - J. Ritchie Carroll All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \**************************************************************************/ #endregion using System; using System.ComponentModel; using System.Globalization; using System.Runtime.CompilerServices; namespace GSF { /// Represents a 3-byte, 24-bit unsigned integer. /// /// /// This class behaves like most other intrinsic unsigned integers but allows a 3-byte, 24-bit integer implementation /// that is often found in many digital-signal processing arenas and different kinds of protocol parsing. An unsigned /// 24-bit integer is typically used to save storage space on disk where its value range of 0 to 16777215 is sufficient, /// but the unsigned Int16 value range of 0 to 65535 is too small. /// /// /// This structure uses an UInt32 internally for storage and most other common expected integer functionality, so using /// a 24-bit integer will not save memory. However, if the 24-bit unsigned integer range (0 to 16777215) suits your /// data needs you can save disk space by only storing the three bytes that this integer actually consumes. You can do /// this by calling the UInt24.GetBytes function to return a three byte binary array that can be serialized to the desired /// destination and then calling the UInt24.GetValue function to restore the UInt24 value from those three bytes. /// /// /// All the standard operators for the UInt24 have been fully defined for use with both UInt24 and UInt32 unsigned integers; /// you should find that without the exception UInt24 can be compared and numerically calculated with an UInt24 or UInt32. /// Necessary casting should be minimal and typical use should be very simple - just as if you are using any other native /// unsigned integer. /// /// [Serializable(), CLSCompliant(false)] public struct UInt24 : IComparable, IFormattable, IConvertible, IComparable, IComparable, IEquatable, IEquatable { #region [ Members ] // Constants private const uint MaxValue32 = 0x00ffffff; // Represents the largest possible value of an UInt24 as an UInt32. private const uint MinValue32 = 0x00000000; // Represents the smallest possible value of an UInt24 as an UInt32. /// High byte bit-mask used when a 24-bit integer is stored within a 32-bit integer. This field is constant. public const uint BitMask = 0xff000000; // Fields private uint m_value; // We internally store the UInt24 value in a 4-byte unsigned integer for convenience #endregion #region [ Constructors ] /// Creates 24-bit unsigned integer from an existing 24-bit unsigned integer. /// A to create the new value from. public UInt24(UInt24 value) { m_value = ApplyBitMask((uint)value); } /// Creates 24-bit unsigned integer from a 32-bit unsigned integer. /// 32-bit unsigned integer to use as new 24-bit unsigned integer value. /// Source values over 24-bit max range will cause an overflow exception. public UInt24(uint value) { ValidateNumericRange(value); m_value = ApplyBitMask(value); } /// Creates 24-bit unsigned integer from three bytes at a specified position in a byte array. /// An array of bytes. /// The starting position within . /// /// You can use this constructor in-lieu of a System.BitConverter.ToUInt24 function. /// Bytes endian order assumed to match that of currently executing process architecture (little-endian on Intel platforms). /// /// cannot be null. /// is greater than length. /// length from is too small to represent a . public UInt24(byte[] value, int startIndex) { m_value = UInt24.GetValue(value, startIndex).m_value; } #endregion #region [ Methods ] /// Returns the UInt24 value as an array of three bytes. /// An array of bytes with length 3. /// /// You can use this function in-lieu of a System.BitConverter.GetBytes function. /// Bytes will be returned in endian order of currently executing process architecture (little-endian on Intel platforms). /// public byte[] GetBytes() { // Return serialized 3-byte representation of UInt24 return UInt24.GetBytes(this); } /// /// Compares this instance to a specified object and returns an indication of their relative values. /// /// An object to compare, or null. /// /// A signed number indicating the relative values of this instance and value. Returns less than zero /// if this instance is less than value, zero if this instance is equal to value, or greater than zero /// if this instance is greater than value. /// /// value is not an UInt32 or UInt24. public int CompareTo(object value) { if ((object)value == null) return 1; if (!(value is uint) && !(value is UInt24)) throw new ArgumentException("Argument must be an UInt32 or an UInt24"); uint num = (uint)value; return (m_value < num ? -1 : (m_value > num ? 1 : 0)); } /// /// Compares this instance to a specified 24-bit unsigned integer and returns an indication of their /// relative values. /// /// An integer to compare. /// /// A signed number indicating the relative values of this instance and value. Returns less than zero /// if this instance is less than value, zero if this instance is equal to value, or greater than zero /// if this instance is greater than value. /// public int CompareTo(UInt24 value) { return CompareTo((uint)value); } /// /// Compares this instance to a specified 32-bit unsigned integer and returns an indication of their /// relative values. /// /// An integer to compare. /// /// A signed number indicating the relative values of this instance and value. Returns less than zero /// if this instance is less than value, zero if this instance is equal to value, or greater than zero /// if this instance is greater than value. /// public int CompareTo(uint value) { return (m_value < value ? -1 : (m_value > value ? 1 : 0)); } /// /// Returns a value indicating whether this instance is equal to a specified object. /// /// An object to compare, or null. /// /// True if obj is an instance of UInt32 or UInt24 and equals the value of this instance; /// otherwise, False. /// public override bool Equals(object obj) { if (obj is uint || obj is UInt24) return Equals((uint)obj); return false; } /// /// Returns a value indicating whether this instance is equal to a specified UInt24 value. /// /// An UInt24 value to compare to this instance. /// /// True if obj has the same value as this instance; otherwise, False. /// public bool Equals(UInt24 obj) { return Equals((uint)obj); } /// /// Returns a value indicating whether this instance is equal to a specified uint value. /// /// An UInt32 value to compare to this instance. /// /// True if obj has the same value as this instance; otherwise, False. /// public bool Equals(uint obj) { return (m_value == obj); } /// /// Returns the hash code for this instance. /// /// /// A 32-bit unsigned integer hash code. /// public override int GetHashCode() { unchecked { return (int)m_value; } } /// /// Converts the numeric value of this instance to its equivalent string representation. /// /// /// The string representation of the value of this instance, consisting of a minus sign if /// the value is negative, and a sequence of digits ranging from 0 to 9 with no leading zeroes. /// public override string ToString() { return m_value.ToString(); } /// /// Converts the numeric value of this instance to its equivalent string representation, using /// the specified format. /// /// A format string. /// /// The string representation of the value of this instance as specified by format. /// public string ToString(string format) { return m_value.ToString(format); } /// /// Converts the numeric value of this instance to its equivalent string representation using the /// specified culture-specific format information. /// /// /// A that supplies culture-specific formatting information. /// /// /// The string representation of the value of this instance as specified by provider. /// public string ToString(IFormatProvider provider) { return m_value.ToString(provider); } /// /// Converts the numeric value of this instance to its equivalent string representation using the /// specified format and culture-specific format information. /// /// A format specification. /// /// A that supplies culture-specific formatting information. /// /// /// The string representation of the value of this instance as specified by format and provider. /// public string ToString(string format, IFormatProvider provider) { return m_value.ToString(format, provider); } /// /// Converts the string representation of a number to its 24-bit unsigned integer equivalent. /// /// A string containing a number to convert. /// /// A 24-bit unsigned integer equivalent to the number contained in s. /// /// s is null. /// /// s represents a number less than UInt24.MinValue or greater than UInt24.MaxValue. /// /// s is not in the correct format. public static UInt24 Parse(string s) { return (UInt24)uint.Parse(s); } /// /// Converts the string representation of a number in a specified style to its 24-bit unsigned integer equivalent. /// /// A string containing a number to convert. /// /// A bitwise combination of System.Globalization.NumberStyles values that indicates the permitted format of s. /// A typical value to specify is System.Globalization.NumberStyles.Integer. /// /// /// A 24-bit unsigned integer equivalent to the number contained in s. /// /// /// style is not a System.Globalization.NumberStyles value. -or- style is not a combination of /// System.Globalization.NumberStyles.AllowHexSpecifier and System.Globalization.NumberStyles.HexNumber values. /// /// s is null. /// /// s represents a number less than UInt24.MinValue or greater than UInt24.MaxValue. /// /// s is not in a format compliant with style. public static UInt24 Parse(string s, NumberStyles style) { return (UInt24)uint.Parse(s, style); } /// /// Converts the string representation of a number in a specified culture-specific format to its 24-bit /// unsigned integer equivalent. /// /// A string containing a number to convert. /// /// A that supplies culture-specific formatting information about s. /// /// /// A 24-bit unsigned integer equivalent to the number contained in s. /// /// s is null. /// /// s represents a number less than UInt24.MinValue or greater than UInt24.MaxValue. /// /// s is not in the correct format. public static UInt24 Parse(string s, IFormatProvider provider) { return (UInt24)uint.Parse(s, provider); } /// /// Converts the string representation of a number in a specified style and culture-specific format to its 24-bit /// unsigned integer equivalent. /// /// A string containing a number to convert. /// /// A bitwise combination of System.Globalization.NumberStyles values that indicates the permitted format of s. /// A typical value to specify is System.Globalization.NumberStyles.Integer. /// /// /// A that supplies culture-specific formatting information about s. /// /// /// A 24-bit unsigned integer equivalent to the number contained in s. /// /// /// style is not a System.Globalization.NumberStyles value. -or- style is not a combination of /// System.Globalization.NumberStyles.AllowHexSpecifier and System.Globalization.NumberStyles.HexNumber values. /// /// s is null. /// /// s represents a number less than UInt24.MinValue or greater than UInt24.MaxValue. /// /// s is not in a format compliant with style. public static UInt24 Parse(string s, NumberStyles style, IFormatProvider provider) { return (UInt24)uint.Parse(s, style, provider); } /// /// Converts the string representation of a number to its 24-bit unsigned integer equivalent. A return value /// indicates whether the conversion succeeded or failed. /// /// A string containing a number to convert. /// /// When this method returns, contains the 24-bit unsigned integer value equivalent to the number contained in s, /// if the conversion succeeded, or zero if the conversion failed. The conversion fails if the s parameter is null, /// is not of the correct format, or represents a number less than UInt24.MinValue or greater than UInt24.MaxValue. /// This parameter is passed uninitialized. /// /// true if s was converted successfully; otherwise, false. public static bool TryParse(string s, out UInt24 result) { uint parseResult; bool parseResponse; parseResponse = uint.TryParse(s, out parseResult); try { result = (UInt24)parseResult; } catch { result = (UInt24)0; parseResponse = false; } return parseResponse; } /// /// Converts the string representation of a number in a specified style and culture-specific format to its /// 24-bit unsigned integer equivalent. A return value indicates whether the conversion succeeded or failed. /// /// A string containing a number to convert. /// /// A bitwise combination of System.Globalization.NumberStyles values that indicates the permitted format of s. /// A typical value to specify is System.Globalization.NumberStyles.Integer. /// /// /// When this method returns, contains the 24-bit unsigned integer value equivalent to the number contained in s, /// if the conversion succeeded, or zero if the conversion failed. The conversion fails if the s parameter is null, /// is not in a format compliant with style, or represents a number less than UInt24.MinValue or greater than /// UInt24.MaxValue. This parameter is passed uninitialized. /// /// /// A object that supplies culture-specific formatting information about s. /// /// true if s was converted successfully; otherwise, false. /// /// style is not a System.Globalization.NumberStyles value. -or- style is not a combination of /// System.Globalization.NumberStyles.AllowHexSpecifier and System.Globalization.NumberStyles.HexNumber values. /// public static bool TryParse(string s, NumberStyles style, IFormatProvider provider, out UInt24 result) { uint parseResult; bool parseResponse; parseResponse = uint.TryParse(s, style, provider, out parseResult); try { result = (UInt24)parseResult; } catch { result = (UInt24)0; parseResponse = false; } return parseResponse; } /// /// Returns the System.TypeCode for value type System.UInt32 (there is no defined type code for an UInt24). /// /// The enumerated constant, System.TypeCode.UInt32. /// /// There is no defined UInt24 type code and since an UInt24 will easily fit inside an UInt32, the /// UInt32 type code is returned. /// public TypeCode GetTypeCode() { return TypeCode.UInt32; } #region [ Explicit IConvertible Implementation ] // These are explicitly implemented on the native integer implementations, so we do the same... bool IConvertible.ToBoolean(IFormatProvider provider) { return Convert.ToBoolean(m_value, provider); } char IConvertible.ToChar(IFormatProvider provider) { return Convert.ToChar(m_value, provider); } sbyte IConvertible.ToSByte(IFormatProvider provider) { return Convert.ToSByte(m_value, provider); } byte IConvertible.ToByte(IFormatProvider provider) { return Convert.ToByte(m_value, provider); } short IConvertible.ToInt16(IFormatProvider provider) { return Convert.ToInt16(m_value, provider); } ushort IConvertible.ToUInt16(IFormatProvider provider) { return Convert.ToUInt16(m_value, provider); } int IConvertible.ToInt32(IFormatProvider provider) { return Convert.ToInt32(m_value, provider); } uint IConvertible.ToUInt32(IFormatProvider provider) { return m_value; } long IConvertible.ToInt64(IFormatProvider provider) { return Convert.ToInt64(m_value, provider); } ulong IConvertible.ToUInt64(IFormatProvider provider) { return Convert.ToUInt64(m_value, provider); } float IConvertible.ToSingle(IFormatProvider provider) { return Convert.ToSingle(m_value, provider); } double IConvertible.ToDouble(IFormatProvider provider) { return Convert.ToDouble(m_value, provider); } decimal IConvertible.ToDecimal(IFormatProvider provider) { return Convert.ToDecimal(m_value, provider); } DateTime IConvertible.ToDateTime(IFormatProvider provider) { return Convert.ToDateTime(m_value, provider); } object IConvertible.ToType(Type type, IFormatProvider provider) { return Convert.ChangeType(m_value, type, provider); } #endregion #endregion #region [ Operators ] // Every effort has been made to make UInt24 as cleanly interoperable with UInt32 as possible... #region [ Comparison Operators ] /// /// Compares the two values for equality. /// /// left hand operand. /// right hand operand. /// value representing the result. public static bool operator ==(UInt24 value1, UInt24 value2) { return value1.Equals(value2); } /// /// Compares the two values for equality. /// /// left hand operand. /// right hand operand. /// value representing the result. public static bool operator ==(uint value1, UInt24 value2) { return value1.Equals((uint)value2); } /// /// Compares the two values for equality. /// /// left hand operand. /// right hand operand. /// value representing the result. public static bool operator ==(UInt24 value1, uint value2) { return ((uint)value1).Equals(value2); } /// /// Compares the two values for inequality. /// /// left hand operand. /// right hand operand. /// value representing the result. public static bool operator !=(UInt24 value1, UInt24 value2) { return !value1.Equals(value2); } /// /// Compares the two values for inequality. /// /// left hand operand. /// right hand operand. /// value representing the result. public static bool operator !=(uint value1, UInt24 value2) { return !value1.Equals((uint)value2); } /// /// Compares the two values for inequality. /// /// left hand operand. /// right hand operand. /// value representing the result. public static bool operator !=(UInt24 value1, uint value2) { return !((uint)value1).Equals(value2); } /// /// Returns true if left value is less than right value. /// /// left hand operand. /// right hand operand. /// value representing the result. public static bool operator <(UInt24 value1, UInt24 value2) { return (value1.CompareTo(value2) < 0); } /// /// Returns true if left value is less than right value. /// /// left hand operand. /// right hand operand. /// value representing the result. public static bool operator <(uint value1, UInt24 value2) { return (value1.CompareTo((uint)value2) < 0); } /// /// Returns true if left value is less than right value. /// /// left hand operand. /// right hand operand. /// value representing the result. public static bool operator <(UInt24 value1, uint value2) { return (value1.CompareTo(value2) < 0); } /// /// Returns true if left value is less or equal to than right value. /// /// left hand operand. /// right hand operand. /// value representing the result. public static bool operator <=(UInt24 value1, UInt24 value2) { return (value1.CompareTo(value2) <= 0); } /// /// Returns true if left value is less or equal to than right value. /// /// left hand operand. /// right hand operand. /// value representing the result. public static bool operator <=(uint value1, UInt24 value2) { return (value1.CompareTo((uint)value2) <= 0); } /// /// Returns true if left value is less or equal to than right value. /// /// left hand operand. /// right hand operand. /// value representing the result. public static bool operator <=(UInt24 value1, uint value2) { return (value1.CompareTo(value2) <= 0); } /// /// Returns true if left value is greater than right value. /// /// left hand operand. /// right hand operand. /// value representing the result. public static bool operator >(UInt24 value1, UInt24 value2) { return (value1.CompareTo(value2) > 0); } /// /// Returns true if left value is greater than right value. /// /// left hand operand. /// right hand operand. /// value representing the result. public static bool operator >(uint value1, UInt24 value2) { return (value1.CompareTo((uint)value2) > 0); } /// /// Returns true if left value is greater than right value. /// /// left hand operand. /// right hand operand. /// value representing the result. public static bool operator >(UInt24 value1, uint value2) { return (value1.CompareTo(value2) > 0); } /// /// Returns true if left value is greater than or equal to right value. /// /// left hand operand. /// right hand operand. /// value representing the result. public static bool operator >=(UInt24 value1, UInt24 value2) { return (value1.CompareTo(value2) >= 0); } /// /// Returns true if left value is greater than or equal to right value. /// /// left hand operand. /// right hand operand. /// value representing the result. public static bool operator >=(uint value1, UInt24 value2) { return (value1.CompareTo((uint)value2) >= 0); } /// /// Returns true if left value is greater than or equal to right value. /// /// left hand operand. /// right hand operand. /// value representing the result. public static bool operator >=(UInt24 value1, uint value2) { return (value1.CompareTo(value2) >= 0); } #endregion #region [ Type Conversion Operators ] #region [ Explicit Narrowing Conversions ] /// /// Explicitly converts value to an . /// /// value to be converted. /// value that is the result of the conversion. public static explicit operator UInt24(Enum value) { return new UInt24(Convert.ToUInt32(value)); } /// /// Explicitly converts value to an . /// /// value to be converted. /// value that is the result of the conversion. public static explicit operator UInt24(string value) { return new UInt24(Convert.ToUInt32(value)); } /// /// Explicitly converts value to an . /// /// value to be converted. /// value that is the result of the conversion. public static explicit operator UInt24(decimal value) { return new UInt24(Convert.ToUInt32(value)); } /// /// Explicitly converts value to an . /// /// value to be converted. /// value that is the result of the conversion. public static explicit operator UInt24(double value) { return new UInt24(Convert.ToUInt32(value)); } /// /// Explicitly converts value to an . /// /// value to be converted. /// value that is the result of the conversion. public static explicit operator UInt24(float value) { return new UInt24(Convert.ToUInt32(value)); } /// /// Explicitly converts value to an . /// /// value to be converted. /// value that is the result of the conversion. public static explicit operator UInt24(ulong value) { return new UInt24(Convert.ToUInt32(value)); } /// /// Explicitly converts value to an . /// /// value to be converted. /// value that is the result of the conversion. public static explicit operator UInt24(uint value) { return new UInt24(value); } /// /// Explicitly converts value to an . /// /// value to be converted. /// value that is the result of the conversion. public static explicit operator UInt24(Int24 value) { return new UInt24((uint)value); } /// /// Explicitly converts value to an . /// /// value to be converted. /// value that is the result of the conversion. public static explicit operator Int24(UInt24 value) { return new Int24((int)value); } /// /// Explicitly converts to . /// /// value to be converted. /// value that is the result of the conversion. public static explicit operator short(UInt24 value) { return (short)((uint)value); } /// /// Explicitly converts to . /// /// value to be converted. /// value that is the result of the conversion. public static explicit operator ushort(UInt24 value) { return (ushort)((uint)value); } /// /// Explicitly converts to . /// /// value to be converted. /// value that is the result of the conversion. public static explicit operator byte(UInt24 value) { return (byte)((uint)value); } #endregion #region [ Implicit Widening Conversions ] /// /// Implicitly converts value to an . /// /// value to be converted. /// value that is the result of the conversion. public static implicit operator UInt24(byte value) { return new UInt24((uint)value); } /// /// Implicitly converts value to an . /// /// value to be converted. /// value that is the result of the conversion. public static implicit operator UInt24(char value) { return new UInt24((uint)value); } /// /// Implicitly converts value to an . /// /// value to be converted. /// value that is the result of the conversion. public static implicit operator UInt24(ushort value) { return new UInt24((uint)value); } /// /// Implicitly converts to . /// /// value to be converted. /// value that is the result of the conversion. public static implicit operator int(UInt24 value) { return ((IConvertible)value).ToInt32(null); } /// /// Implicitly converts to . /// /// value to be converted. /// value that is the result of the conversion. public static implicit operator uint(UInt24 value) { return ((IConvertible)value).ToUInt32(null); } /// /// Implicitly converts to . /// /// value to be converted. /// value that is the result of the conversion. public static implicit operator long(UInt24 value) { return ((IConvertible)value).ToInt64(null); } /// /// Implicitly converts to . /// /// value to be converted. /// value that is the result of the conversion. public static implicit operator ulong(UInt24 value) { return ((IConvertible)value).ToUInt64(null); } /// /// Implicitly converts to . /// /// value to be converted. /// value that is the result of the conversion. public static implicit operator double(UInt24 value) { return ((IConvertible)value).ToDouble(null); } /// /// Implicitly converts to . /// /// value to be converted. /// value that is the result of the conversion. public static implicit operator float(UInt24 value) { return ((IConvertible)value).ToSingle(null); } /// /// Implicitly converts to . /// /// value to be converted. /// value that is the result of the conversion. public static implicit operator decimal(UInt24 value) { return ((IConvertible)value).ToDecimal(null); } /// /// Implicitly converts to . /// /// value to be converted. /// value that is the result of the conversion. public static implicit operator string(UInt24 value) { return value.ToString(); } #endregion #endregion #region [ Boolean and Bitwise Operators ] /// /// Returns true if value is greater than zero. /// /// value to evaluate. /// value indicating whether the value is greater than zero. public static bool operator true(UInt24 value) { return (value > 0); } /// /// Returns true if value is equal to zero. /// /// value to evaluate. /// value indicating whether the value is equal than zero. public static bool operator false(UInt24 value) { return (value == 0); } /// /// Returns bitwise complement of value. /// /// value to evaluate. /// value representing the complement of the input value. public static UInt24 operator ~(UInt24 value) { return (UInt24)ApplyBitMask(~(uint)value); } /// /// Returns logical bitwise AND of values. /// /// left hand operand. /// right hand operand. /// value representing the logical bitwise AND of the values. public static UInt24 operator &(UInt24 value1, UInt24 value2) { return (UInt24)ApplyBitMask((uint)value1 & (uint)value2); } /// /// Returns logical bitwise AND of values. /// /// left hand operand. /// right hand operand. /// value representing the logical bitwise AND of the values. public static uint operator &(uint value1, UInt24 value2) { return (value1 & (uint)value2); } /// /// Returns logical bitwise AND of values. /// /// left hand operand. /// right hand operand. /// value representing the logical bitwise AND of the values. public static uint operator &(UInt24 value1, uint value2) { return ((uint)value1 & value2); } /// /// Returns logical bitwise OR of values. /// /// left hand operand. /// right hand operand. /// value representing the logical bitwise OR of the values. public static UInt24 operator |(UInt24 value1, UInt24 value2) { return (UInt24)ApplyBitMask((uint)value1 | (uint)value2); } /// /// Returns logical bitwise OR of values. /// /// left hand operand. /// right hand operand. /// value representing the logical bitwise OR of the values. public static uint operator |(uint value1, UInt24 value2) { return (value1 | (uint)value2); } /// /// Returns logical bitwise OR of values. /// /// left hand operand. /// right hand operand. /// value representing the logical bitwise OR of the values. public static uint operator |(UInt24 value1, uint value2) { return ((uint)value1 | value2); } /// /// Returns logical bitwise exclusive-OR of values. /// /// left hand operand. /// right hand operand. /// value representing the logical bitwise exclusive-OR of the values. public static UInt24 operator ^(UInt24 value1, UInt24 value2) { return (UInt24)ApplyBitMask((uint)value1 ^ (uint)value2); } /// /// Returns logical bitwise exclusive-OR of values. /// /// left hand operand. /// right hand operand. /// value representing the logical bitwise exclusive-OR of the values. public static uint operator ^(uint value1, UInt24 value2) { return (value1 ^ (uint)value2); } /// /// Returns logical bitwise exclusive-OR of values. /// /// left hand operand. /// right hand operand. /// value representing the logical bitwise exclusive-OR of the values. public static uint operator ^(UInt24 value1, uint value2) { return ((uint)value1 ^ value2); } /// /// Returns value after right shifts of first value by the number of bits specified by second value. /// /// value to right shift. /// value indicating the number of bits to right shift by. /// value as result of right shift operation. public static UInt24 operator >>(UInt24 value, int shifts) { return (UInt24)ApplyBitMask((uint)value >> shifts); } /// /// Returns value after left shifts of first value by the number of bits specified by second value. /// /// value to left shift. /// value indicating the number of bits to left shift by. /// value as result of left shift operation. public static UInt24 operator <<(UInt24 value, int shifts) { return (UInt24)ApplyBitMask((uint)value << shifts); } #endregion #region [ Arithmetic Operators ] /// /// Returns computed remainder after dividing first value by the second. /// /// left hand operand. /// right hand operand. /// value as result of modulus operation. public static UInt24 operator %(UInt24 value1, UInt24 value2) { return (UInt24)((uint)value1 % (uint)value2); } /// /// Returns computed remainder after dividing first value by the second. /// /// left hand operand. /// right hand operand. /// value as result of modulus operation. public static uint operator %(uint value1, UInt24 value2) { return (value1 % (uint)value2); } /// /// Returns computed remainder after dividing first value by the second. /// /// left hand operand. /// right hand operand. /// value as result of modulus operation. public static uint operator %(UInt24 value1, uint value2) { return ((uint)value1 % value2); } /// /// Returns computed sum of values. /// /// left hand operand. /// right hand operand. /// value as result of addition operation. public static UInt24 operator +(UInt24 value1, UInt24 value2) { return (UInt24)((uint)value1 + (uint)value2); } /// /// Returns computed sum of values. /// /// left hand operand. /// right hand operand. /// value as result of addition operation. public static uint operator +(uint value1, UInt24 value2) { return (value1 + (uint)value2); } /// /// Returns computed sum of values. /// /// left hand operand. /// right hand operand. /// value as result of addition operation. public static uint operator +(UInt24 value1, uint value2) { return ((uint)value1 + value2); } /// /// Returns computed difference of values. /// /// left hand operand. /// right hand operand. /// value as result of subtraction operation. public static UInt24 operator -(UInt24 value1, UInt24 value2) { return (UInt24)((uint)value1 - (uint)value2); } /// /// Returns computed difference of values. /// /// left hand operand. /// right hand operand. /// value as result of subtraction operation. public static uint operator -(uint value1, UInt24 value2) { return (value1 - (uint)value2); } /// /// Returns computed difference of values. /// /// left hand operand. /// right hand operand. /// value as result of subtraction operation. public static uint operator -(UInt24 value1, uint value2) { return ((uint)value1 - value2); } /// /// Returns incremented value. /// /// The operand. /// result of increment. public static UInt24 operator ++(UInt24 value) { return (UInt24)(value + 1); } /// /// Returns decremented value. /// /// The operand. /// result of decrement. public static UInt24 operator --(UInt24 value) { return (UInt24)(value - 1); } /// /// Returns computed product of values. /// /// left hand operand. /// right hand operand. /// value as result of multiplication operation. public static UInt24 operator *(UInt24 value1, UInt24 value2) { return (UInt24)((uint)value1 * (uint)value2); } /// /// Returns computed product of values. /// /// left hand operand. /// right hand operand. /// value as result of multiplication operation. public static uint operator *(uint value1, UInt24 value2) { return (value1 * (uint)value2); } /// /// Returns computed product of values. /// /// left hand operand. /// right hand operand. /// value as result of multiplication operation. public static uint operator *(UInt24 value1, uint value2) { return ((uint)value1 * value2); } // Integer division operators /// /// Returns computed division of values. /// /// left hand operand. /// right hand operand. /// value as result of division operation. public static UInt24 operator /(UInt24 value1, UInt24 value2) { return (UInt24)((uint)value1 / (uint)value2); } /// /// Returns computed division of values. /// /// left hand operand. /// right hand operand. /// value as result of division operation. public static uint operator /(uint value1, UInt24 value2) { return (value1 / (uint)value2); } /// /// Returns computed division of values. /// /// left hand operand. /// right hand operand. /// value as result of division operation. public static uint operator /(UInt24 value1, uint value2) { return ((uint)value1 / value2); } //// Standard division operators //public static double operator /(UInt24 value1, UInt24 value2) //{ // return ((double)value1 / (double)value2); //} //public static double operator /(uint value1, UInt24 value2) //{ // return ((double)value1 / (double)value2); //} //public static double operator /(UInt24 value1, uint value2) //{ // return ((double)value1 / (double)value2); //} // C# doesn't expose an exponent operator but some other .NET languages do, // so we expose the operator via its native special IL function name /// /// Returns result of first value raised to power of second value. /// /// left hand operand. /// right hand operand. /// value as result of operation. [EditorBrowsable(EditorBrowsableState.Advanced), SpecialName()] public static double op_Exponent(UInt24 value1, UInt24 value2) { return Math.Pow((double)value1, (double)value2); } /// /// Returns result of first value raised to power of second value. /// /// left hand operand. /// right hand operand. /// value as result of operation. [EditorBrowsable(EditorBrowsableState.Advanced), SpecialName()] public static double op_Exponent(int value1, UInt24 value2) { return Math.Pow((double)value1, (double)value2); } /// /// Returns result of first value raised to power of second value. /// /// left hand operand. /// right hand operand. /// value as result of operation. [EditorBrowsable(EditorBrowsableState.Advanced), SpecialName()] public static double op_Exponent(UInt24 value1, int value2) { return Math.Pow((double)value1, (double)value2); } #endregion #endregion #region [ Static ] /// /// Represents the largest possible value of an Int24. This field is constant. /// public static readonly UInt24 MaxValue = (UInt24)MaxValue32; /// /// Represents the smallest possible value of an Int24. This field is constant. /// public static readonly UInt24 MinValue = (UInt24)MinValue32; /// Returns the specified UInt24 value as an array of three bytes. /// UInt24 value to convert to bytes. /// An array of bytes with length 3. /// /// You can use this function in-lieu of a System.BitConverter.GetBytes(UInt24) function. /// Bytes will be returned in endian order of currently executing process architecture (little-endian on Intel platforms). /// public static byte[] GetBytes(UInt24 value) { // We use a 32-bit integer to store 24-bit integer internally byte[] int32Bytes = BitConverter.GetBytes((uint)value); byte[] int24Bytes = new byte[3]; if (BitConverter.IsLittleEndian) { // Copy little-endian bytes starting at index 0 Buffer.BlockCopy(int32Bytes, 0, int24Bytes, 0, 3); } else { // Copy big-endian bytes starting at index 1 Buffer.BlockCopy(int32Bytes, 1, int24Bytes, 0, 3); } // Return serialized 3-byte representation of UInt24 return int24Bytes; } /// Returns a 24-bit unsigned integer from three bytes at a specified position in a byte array. /// An array of bytes. /// The starting position within value. /// A 24-bit unsigned integer formed by three bytes beginning at startIndex. /// /// You can use this function in-lieu of a System.BitConverter.ToUInt24 function. /// Bytes endian order assumed to match that of currently executing process architecture (little-endian on Intel platforms). /// /// cannot be null. /// is greater than length. /// length from is too small to represent an . public static UInt24 GetValue(byte[] value, int startIndex) { if ((object)value == null) throw new ArgumentNullException("value"); if (startIndex >= value.Length) throw new ArgumentOutOfRangeException("startIndex", "startIndex is greater than value length"); if (startIndex > value.Length - 3) throw new ArgumentException("value length from startIndex is too small to represent an UInt24"); // We use a 32-bit integer to store 24-bit integer internally byte[] bytes = new byte[4]; if (BitConverter.IsLittleEndian) { // Copy little-endian bytes starting at index 0 leaving byte at index 3 blank Buffer.BlockCopy(value, 0, bytes, 0, 3); } else { // Copy big-endian bytes starting at index 1 leaving byte at index 0 blank Buffer.BlockCopy(value, 0, bytes, 1, 3); } // Deserialize value return (UInt24)ApplyBitMask(BitConverter.ToUInt32(bytes, 0)); } private static void ValidateNumericRange(uint value) { if (value > MaxValue32) throw new OverflowException(string.Format("Value of {0} will not fit in a 24-bit unsigned integer", value)); } private static uint ApplyBitMask(uint value) { // For unsigned values, all we do is clear all the high bits (keeps 32-bit unsigned number in 24-bit unsigned range)... return (value & ~BitMask); } #endregion } }