//******************************************************************************************************
// Int24.cs - Gbtc
//
// Copyright © 2012, 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 MIT License (MIT), 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/MIT
//
// 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/3/2009 - Josh L. Patterson
// Updated comments.
// 08/11/2009 - Josh L. Patterson
// Updated comments.
// 09/14/2009 - Stephen C. Wills
// Added new header and license agreement.
// 12/14/2012 - Starlynn 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 signed integer.
///
///
/// This class behaves like most other intrinsic signed 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. A signed
/// 24-bit integer is typically used to save storage space on disk where its value range of -8388608 to 8388607 is
/// sufficient, but the signed Int16 value range of -32768 to 32767 is too small.
///
///
/// This structure uses an Int32 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 signed integer range (-8388608 to 8388607) 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 Int24.GetBytes function to return a three byte binary array that can be serialized to the desired
/// destination and then calling the Int24.GetValue function to restore the Int24 value from those three bytes.
///
///
/// All the standard operators for the Int24 have been fully defined for use with both Int24 and Int32 signed integers;
/// you should find that without the exception Int24 can be compared and numerically calculated with an Int24 or Int32.
/// Necessary casting should be minimal and typical use should be very simple - just as if you are using any other native
/// signed integer.
///
///
[Serializable]
public struct Int24 : IComparable, IFormattable, IConvertible, IComparable, IComparable, IEquatable, IEquatable
{
#region [ Members ]
// Constants
private const int MaxValue32 = 8388607; // Represents the largest possible value of an Int24 as an Int32.
private const int MinValue32 = -8388608; // Represents the smallest possible value of an Int24 as an Int32.
/// High byte bit-mask used when a 24-bit integer is stored within a 32-bit integer. This field is constant.
public const int BitMask = -16777216;
// Fields
private readonly int m_value; // We internally store the Int24 value in a 4-byte integer for convenience
#endregion
#region [ Constructors ]
/// Creates 24-bit signed integer from an existing 24-bit signed integer.
/// 24-but signed integer to create new Int24 from.
public Int24(Int24 value)
{
m_value = ApplyBitMask((int)value);
}
/// Creates 24-bit signed integer from a 32-bit signed integer.
/// 32-bit signed integer to use as new 24-bit signed integer value.
/// Source values outside 24-bit min/max range will cause an overflow exception.
public Int24(int value)
{
ValidateNumericRange(value);
m_value = ApplyBitMask(value);
}
/// Creates 24-bit signed 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.ToInt24 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 Int24(byte[] value, int startIndex)
{
m_value = GetValue(value, startIndex).m_value;
}
#endregion
#region [ Methods ]
/// Returns the Int24 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 Int24
return 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 Int32 or Int24.
public int CompareTo(object value)
{
if ((object)value == null)
return 1;
if (!(value is int) && !(value is Int24))
throw new ArgumentException("Argument must be an Int32 or an Int24");
int num = (int)value;
return (m_value < num ? -1 : (m_value > num ? 1 : 0));
}
///
/// Compares this instance to a specified 24-bit signed 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(Int24 value)
{
return CompareTo((int)value);
}
///
/// Compares this instance to a specified 32-bit signed 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(int 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 Int32 or Int24 and equals the value of this instance;
/// otherwise, False.
///
public override bool Equals(object obj)
{
if (obj is int || obj is Int24)
return Equals((int)obj);
return false;
}
///
/// Returns a value indicating whether this instance is equal to a specified Int24 value.
///
/// An Int24 value to compare to this instance.
///
/// True if obj has the same value as this instance; otherwise, False.
///
public bool Equals(Int24 obj)
{
return Equals((int)obj);
}
///
/// Returns a value indicating whether this instance is equal to a specified Int32 value.
///
/// An Int32 value to compare to this instance.
///
/// True if obj has the same value as this instance; otherwise, False.
///
public bool Equals(int obj)
{
return (m_value == obj);
}
///
/// Returns the hash code for this instance.
///
///
/// A 32-bit signed integer hash code.
///
public override int GetHashCode()
{
return 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 signed integer equivalent.
///
/// A string containing a number to convert.
///
/// A 24-bit signed integer equivalent to the number contained in s.
///
/// s is null.
///
/// s represents a number less than Int24.MinValue or greater than Int24.MaxValue.
///
/// s is not in the correct format.
public static Int24 Parse(string s)
{
return (Int24)int.Parse(s);
}
///
/// Converts the string representation of a number in a specified style to its 24-bit signed 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 signed 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 Int24.MinValue or greater than Int24.MaxValue.
///
/// s is not in a format compliant with style.
public static Int24 Parse(string s, NumberStyles style)
{
return (Int24)int.Parse(s, style);
}
///
/// Converts the string representation of a number in a specified culture-specific format to its 24-bit
/// signed integer equivalent.
///
/// A string containing a number to convert.
///
/// A that supplies culture-specific formatting information about s.
///
///
/// A 24-bit signed integer equivalent to the number contained in s.
///
/// s is null.
///
/// s represents a number less than Int24.MinValue or greater than Int24.MaxValue.
///
/// s is not in the correct format.
public static Int24 Parse(string s, IFormatProvider provider)
{
return (Int24)int.Parse(s, provider);
}
///
/// Converts the string representation of a number in a specified style and culture-specific format to its 24-bit
/// signed 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 signed 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 Int24.MinValue or greater than Int24.MaxValue.
///
/// s is not in a format compliant with style.
public static Int24 Parse(string s, NumberStyles style, IFormatProvider provider)
{
return (Int24)int.Parse(s, style, provider);
}
///
/// Converts the string representation of a number to its 24-bit signed 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 signed 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 Int24.MinValue or greater than Int24.MaxValue.
/// This parameter is passed uninitialized.
///
/// true if s was converted successfully; otherwise, false.
public static bool TryParse(string s, out Int24 result)
{
int parseResult;
bool parseResponse;
parseResponse = int.TryParse(s, out parseResult);
try
{
result = (Int24)parseResult;
}
catch
{
result = (Int24)0;
parseResponse = false;
}
return parseResponse;
}
///
/// Converts the string representation of a number in a specified style and culture-specific format to its
/// 24-bit signed 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 signed 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 Int24.MinValue or greater than
/// Int24.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 Int24 result)
{
int parseResult;
bool parseResponse;
parseResponse = int.TryParse(s, style, provider, out parseResult);
try
{
result = (Int24)parseResult;
}
catch
{
result = (Int24)0;
parseResponse = false;
}
return parseResponse;
}
///
/// Returns the System.TypeCode for value type System.Int32 (there is no defined type code for an Int24).
///
/// The enumerated constant, System.TypeCode.Int32.
///
/// There is no defined Int24 type code and since an Int24 will easily fit inside an Int32, the
/// Int32 type code is returned.
///
public TypeCode GetTypeCode()
{
return TypeCode.Int32;
}
#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 m_value;
}
uint IConvertible.ToUInt32(IFormatProvider provider)
{
return Convert.ToUInt32(m_value, provider);
}
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 Int24 as cleanly interoperable with Int32 as possible...
#region [ Comparison Operators ]
///
/// Compares the two values for equality.
///
/// Left hand operand.
/// Right hand operand.
/// Boolean value indicating equality.
public static bool operator ==(Int24 value1, Int24 value2)
{
return value1.Equals(value2);
}
///
/// Compares the two values for equality.
///
/// Left hand operand.
/// Right hand operand.
/// Boolean value indicating equality.
public static bool operator ==(int value1, Int24 value2)
{
return value1.Equals((int)value2);
}
///
/// Compares the two values for equality.
///
/// Left hand operand.
/// Right hand operand.
/// Boolean value indicating equality.
public static bool operator ==(Int24 value1, int value2)
{
return ((int)value1).Equals(value2);
}
///
/// Compares the two values for inequality.
///
/// Left hand operand.
/// Right hand operand.
/// Boolean indicating the result of the inequality.
public static bool operator !=(Int24 value1, Int24 value2)
{
return !value1.Equals(value2);
}
///
/// Compares the two values for inequality.
///
/// Left hand operand.
/// Right hand operand.
/// Boolean indicating the result of the inequality.
public static bool operator !=(int value1, Int24 value2)
{
return !value1.Equals((int)value2);
}
///
/// Compares the two values for inequality.
///
/// Left hand operand.
/// Right hand operand.
/// Boolean indicating the result of the inequality.
public static bool operator !=(Int24 value1, int value2)
{
return !((int)value1).Equals(value2);
}
///
/// Returns true if left value is less than right value.
///
/// Left hand operand.
/// Right hand operand.
/// Boolean indicating whether the left value was less than the right value.
public static bool operator <(Int24 value1, Int24 value2)
{
return (value1.CompareTo(value2) < 0);
}
///
/// Returns true if left value is less than right value.
///
/// Left hand operand.
/// Right hand operand.
/// Boolean indicating whether the left value was less than the right value.
public static bool operator <(int value1, Int24 value2)
{
return (value1.CompareTo((int)value2) < 0);
}
///
/// Returns true if left value is less than right value.
///
/// Left hand operand.
/// Right hand operand.
/// Boolean indicating whether the left value was less than the right value.
public static bool operator <(Int24 value1, int 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.
/// Boolean indicating whether the left value was less than the right value.
public static bool operator <=(Int24 value1, Int24 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.
/// Boolean indicating whether the left value was less than the right value.
public static bool operator <=(int value1, Int24 value2)
{
return (value1.CompareTo((int)value2) <= 0);
}
///
/// Returns true if left value is less or equal to than right value.
///
/// Left hand operand.
/// Right hand operand.
/// Boolean indicating whether the left value was less than the right value.
public static bool operator <=(Int24 value1, int value2)
{
return (value1.CompareTo(value2) <= 0);
}
///
/// Returns true if left value is greater than right value.
///
/// Left hand operand.
/// Right hand operand.
/// Boolean indicating whether the left value was greater than the right value.
public static bool operator >(Int24 value1, Int24 value2)
{
return (value1.CompareTo(value2) > 0);
}
///
/// Returns true if left value is greater than right value.
///
/// Left hand operand.
/// Right hand operand.
/// Boolean indicating whether the left value was greater than the right value.
public static bool operator >(int value1, Int24 value2)
{
return (value1.CompareTo((int)value2) > 0);
}
///
/// Returns true if left value is greater than right value.
///
/// Left hand operand.
/// Right hand operand.
/// Boolean indicating whether the left value was greater than the right value.
public static bool operator >(Int24 value1, int 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.
/// Boolean indicating whether the left value was greater than or equal to the right value.
public static bool operator >=(Int24 value1, Int24 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.
/// Boolean indicating whether the left value was greater than or equal to the right value.
public static bool operator >=(int value1, Int24 value2)
{
return (value1.CompareTo((int)value2) >= 0);
}
///
/// Returns true if left value is greater than or equal to right value.
///
/// Left hand operand.
/// Right hand operand.
/// Boolean indicating whether the left value was greater than or equal to the right value.
public static bool operator >=(Int24 value1, int value2)
{
return (value1.CompareTo(value2) >= 0);
}
#endregion
#region [ Type Conversion Operators ]
#region [ Explicit Narrowing Conversions ]
///
/// Explicitly converts value to an .
///
/// Enum value that is converted.
/// Int24
public static explicit operator Int24(Enum value)
{
return new Int24(Convert.ToInt32(value));
}
///
/// Explicitly converts value to an .
///
/// String value that is converted.
/// Int24
public static explicit operator Int24(string value)
{
return new Int24(Convert.ToInt32(value));
}
///
/// Explicitly converts value to an .
///
/// Decimal value that is converted.
/// Int24
public static explicit operator Int24(decimal value)
{
return new Int24(Convert.ToInt32(value));
}
///
/// Explicitly converts value to an .
///
/// Double value that is converted.
/// Int24
public static explicit operator Int24(double value)
{
return new Int24(Convert.ToInt32(value));
}
///
/// Explicitly converts value to an .
///
/// Float value that is converted.
/// Int24
public static explicit operator Int24(float value)
{
return new Int24(Convert.ToInt32(value));
}
///
/// Explicitly converts value to an .
///
/// Long value that is converted.
/// Int24
public static explicit operator Int24(long value)
{
return new Int24(Convert.ToInt32(value));
}
///
/// Explicitly converts value to an .
///
/// Integer value that is converted.
/// Int24
public static explicit operator Int24(int value)
{
return new Int24(value);
}
///
/// Explicitly converts to .
///
/// Int24 value that is converted.
/// Short
public static explicit operator short(Int24 value)
{
return (short)((int)value);
}
///
/// Explicitly converts to .
///
/// Int24 value that is converted.
/// Unsigned Short
public static explicit operator ushort(Int24 value)
{
return (ushort)((uint)value);
}
///
/// Explicitly converts to .
///
/// Int24 value that is converted.
/// Byte
public static explicit operator byte(Int24 value)
{
return (byte)((int)value);
}
#endregion
#region [ Implicit Widening Conversions ]
///
/// Implicitly converts value to an .
///
/// Byte value that is converted to an .
/// An value.
public static implicit operator Int24(byte value)
{
return new Int24((int)value);
}
///
/// Implicitly converts value to an .
///
/// Char value that is converted to an .
/// An value.
public static implicit operator Int24(char value)
{
return new Int24((int)value);
}
///
/// Implicitly converts value to an .
///
/// Short value that is converted to an .
/// An value.
public static implicit operator Int24(short value)
{
return new Int24((int)value);
}
///
/// Implicitly converts to .
///
/// value that is converted to an .
/// An value.
public static implicit operator int(Int24 value)
{
return ((IConvertible)value).ToInt32(null);
}
///
/// Implicitly converts to .
///
/// value that is converted to an unsigned integer.
/// Unsigned integer
public static implicit operator uint(Int24 value)
{
return ((IConvertible)value).ToUInt32(null);
}
///
/// Implicitly converts to .
///
/// value that is converted to an .
/// An value.
public static implicit operator long(Int24 value)
{
return ((IConvertible)value).ToInt64(null);
}
///
/// Implicitly converts to .
///
/// value that is converted to an .
/// An value.
public static implicit operator ulong(Int24 value)
{
return ((IConvertible)value).ToUInt64(null);
}
///
/// Implicitly converts to .
///
/// value that is converted to an .
/// A value.
public static implicit operator double(Int24 value)
{
return ((IConvertible)value).ToDouble(null);
}
///
/// Implicitly converts to .
///
/// value that is converted to an .
/// A value.
public static implicit operator float(Int24 value)
{
return ((IConvertible)value).ToSingle(null);
}
///
/// Implicitly converts to .
///
/// value that is converted to an .
/// A value.
public static implicit operator decimal(Int24 value)
{
return ((IConvertible)value).ToDecimal(null);
}
///
/// Implicitly converts to .
///
/// value that is converted to an .
/// A value.
public static implicit operator string(Int24 value)
{
return value.ToString();
}
#endregion
#endregion
#region [ Boolean and Bitwise Operators ]
///
/// Returns true if value is not zero.
///
/// Int24 value to test.
/// Boolean to indicate whether the value was not equal to zero.
public static bool operator true(Int24 value)
{
return (value != 0);
}
///
/// Returns true if value is equal to zero.
///
/// Int24 value to test.
/// Boolean to indicate whether the value was equal to zero.
public static bool operator false(Int24 value)
{
return (value == 0);
}
///
/// Returns bitwise complement of value.
///
/// value as operand.
/// as result.
public static Int24 operator ~(Int24 value)
{
return (Int24)ApplyBitMask(~(int)value);
}
///
/// Returns logical bitwise AND of values.
///
/// Left hand operand.
/// Right hand operand.
/// Int24 as result of operation.
public static Int24 operator &(Int24 value1, Int24 value2)
{
return (Int24)ApplyBitMask((int)value1 & (int)value2);
}
///
/// Returns logical bitwise AND of values.
///
/// Left hand operand.
/// Right hand operand.
/// Integer as result of operation.
public static int operator &(int value1, Int24 value2)
{
return (value1 & (int)value2);
}
///
/// Returns logical bitwise AND of values.
///
/// Left hand operand.
/// Right hand operand.
/// Integer as result of operation.
public static int operator &(Int24 value1, int value2)
{
return ((int)value1 & value2);
}
///
/// Returns logical bitwise OR of values.
///
/// Left hand operand.
/// Right hand operand.
/// Int24 as result of operation.
public static Int24 operator |(Int24 value1, Int24 value2)
{
return (Int24)ApplyBitMask((int)value1 | (int)value2);
}
///
/// Returns logical bitwise OR of values.
///
/// Left hand operand.
/// Right hand operand.
/// Integer as result of operation.
public static int operator |(int value1, Int24 value2)
{
return (value1 | (int)value2);
}
///
/// Returns logical bitwise OR of values.
///
/// Left hand operand.
/// Right hand operand.
/// Integer as result of operation.
public static int operator |(Int24 value1, int value2)
{
return ((int)value1 | value2);
}
///
/// Returns logical bitwise exclusive-OR of values.
///
/// Left hand operand.
/// Right hand operand.
/// Integer value of the resulting exclusive-OR operation.
public static Int24 operator ^(Int24 value1, Int24 value2)
{
return (Int24)ApplyBitMask((int)value1 ^ (int)value2);
}
///
/// Returns logical bitwise exclusive-OR of values.
///
/// Left hand operand.
/// Right hand operand.
/// Integer value of the resulting exclusive-OR operation.
public static int operator ^(int value1, Int24 value2)
{
return (value1 ^ (int)value2);
}
///
/// Returns logical bitwise exclusive-OR of values.
///
/// Left hand operand.
/// Right hand operand.
/// Integer value of the resulting exclusive-OR operation.
public static int operator ^(Int24 value1, int value2)
{
return ((int)value1 ^ value2);
}
///
/// Returns value after right shifts of first value by the number of bits specified by second value.
///
/// value to shift.
/// shifts indicates how many places to shift.
/// An value.
public static Int24 operator >>(Int24 value, int shifts)
{
return (Int24)(ApplyBitMask((int)value >> shifts));
}
///
/// Returns value after left shifts of first value by the number of bits specified by second value.
///
/// value to shift.
/// shifts indicates how many places to shift.
/// An value.
public static Int24 operator <<(Int24 value, int shifts)
{
return (Int24)(ApplyBitMask((int)value << shifts));
}
#endregion
#region [ Arithmetic Operators ]
///
/// Returns computed remainder after dividing first value by the second.
///
/// value as numerator.
/// value as denominator.
/// as remainder
public static Int24 operator %(Int24 value1, Int24 value2)
{
return (Int24)((int)value1 % (int)value2);
}
///
/// Returns computed remainder after dividing first value by the second.
///
/// value as numerator.
/// value as denominator.
/// as remainder
public static int operator %(int value1, Int24 value2)
{
return (value1 % (int)value2);
}
///
/// Returns computed remainder after dividing first value by the second.
///
/// value as numerator.
/// value as denominator.
/// as remainder
public static int operator %(Int24 value1, int value2)
{
return ((int)value1 % value2);
}
///
/// Returns computed sum of values.
///
/// Left hand operand.
/// Right hand operand.
/// Int24 result of addition.
public static Int24 operator +(Int24 value1, Int24 value2)
{
return (Int24)((int)value1 + (int)value2);
}
///
/// Returns computed sum of values.
///
/// Left hand operand.
/// Right hand operand.
/// Integer result of addition.
public static int operator +(int value1, Int24 value2)
{
return (value1 + (int)value2);
}
///
/// Returns computed sum of values.
///
/// Left hand operand.
/// Right hand operand.
/// Integer result of addition.
public static int operator +(Int24 value1, int value2)
{
return ((int)value1 + value2);
}
///
/// Returns computed difference of values.
///
/// Left hand operand.
/// Right hand operand.
/// Int24 result of subtraction.
public static Int24 operator -(Int24 value1, Int24 value2)
{
return (Int24)((int)value1 - (int)value2);
}
///
/// Returns computed difference of values.
///
/// Left hand operand.
/// Right hand operand.
/// Integer result of subtraction.
public static int operator -(int value1, Int24 value2)
{
return (value1 - (int)value2);
}
///
/// Returns computed difference of values.
///
/// Left hand operand.
/// Right hand operand.
/// Integer result of subtraction.
public static int operator -(Int24 value1, int value2)
{
return ((int)value1 - value2);
}
///
/// Returns incremented value.
///
/// The operand.
/// Int24 result of increment.
public static Int24 operator ++(Int24 value)
{
return (Int24)(value + 1);
}
///
/// Returns decremented value.
///
/// The operand.
/// Int24 result of decrement.
public static Int24 operator --(Int24 value)
{
return (Int24)(value - 1);
}
///
/// Returns computed product of values.
///
/// value as left hand operand.
/// value as right hand operand.
/// as result
public static Int24 operator *(Int24 value1, Int24 value2)
{
return (Int24)((int)value1 * (int)value2);
}
///
/// Returns computed product of values.
///
/// value as left hand operand.
/// value as right hand operand.
/// as result
public static int operator *(int value1, Int24 value2)
{
return (value1 * (int)value2);
}
///
/// Returns computed product of values.
///
/// value as left hand operand.
/// value as right hand operand.
/// as result
public static int operator *(Int24 value1, int value2)
{
return ((int)value1 * value2);
}
// Integer division operators
///
/// Returns computed division of values.
///
/// Left hand operand.
/// Right hand operand.
/// Int24 result of operation.
public static Int24 operator /(Int24 value1, Int24 value2)
{
return (Int24)((int)value1 / (int)value2);
}
///
/// Returns computed division of values.
///
/// Left hand operand.
/// Right hand operand.
/// Integer result of operation.
public static int operator /(int value1, Int24 value2)
{
return (value1 / (int)value2);
}
///
/// Returns computed division of values.
///
/// Left hand operand.
/// Right hand operand.
/// Integer result of operation.
public static int operator /(Int24 value1, int value2)
{
return ((int)value1 / value2);
}
//// Standard division operators
//public static double operator /(Int24 value1, Int24 value2)
//{
// return ((double)value1 / (double)value2);
//}
//public static double operator /(int value1, Int24 value2)
//{
// return ((double)value1 / (double)value2);
//}
//public static double operator /(Int24 value1, int 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.
/// Double that is the result of the operation.
[EditorBrowsable(EditorBrowsableState.Advanced), SpecialName]
public static double op_Exponent(Int24 value1, Int24 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.
/// Double that is the result of the operation.
[EditorBrowsable(EditorBrowsableState.Advanced), SpecialName]
public static double op_Exponent(int value1, Int24 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.
/// Double that is the result of the operation.
[EditorBrowsable(EditorBrowsableState.Advanced), SpecialName]
public static double op_Exponent(Int24 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 Int24 MaxValue = (Int24)MaxValue32;
///
/// Represents the smallest possible value of an Int24. This field is constant.
///
public static readonly Int24 MinValue = (Int24)MinValue32;
/// Returns the specified Int24 value as an array of three bytes.
/// Int24 value to convert to bytes.
/// An array of bytes with length 3.
///
/// You can use this function in-lieu of a System.BitConverter.GetBytes(Int24) function.
/// Bytes will be returned in endian order of currently executing process architecture (little-endian on Intel platforms).
///
public static byte[] GetBytes(Int24 value)
{
// We use a 32-bit integer to store 24-bit integer internally
byte[] data = new byte[3];
int valueInt = value;
if (BitConverter.IsLittleEndian)
{
data[0] = (byte)valueInt;
data[1] = (byte)(valueInt >> 8);
data[2] = (byte)(valueInt >> 16);
}
else
{
data[0] = (byte)(valueInt >> 16);
data[1] = (byte)(valueInt >> 8);
data[2] = (byte)(valueInt);
}
// Return serialized 3-byte representation of Int24
return data;
}
/// Returns a 24-bit signed integer from three bytes at a specified position in a byte array.
/// An array of bytes.
/// The starting position within value.
/// A 24-bit signed integer formed by three bytes beginning at startIndex.
///
/// You can use this function in-lieu of a System.BitConverter.ToInt24 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 Int24 GetValue(byte[] value, int startIndex)
{
value.ValidateParameters(startIndex, 3);
int valueInt;
if (BitConverter.IsLittleEndian)
{
valueInt = value[0] |
value[1] << 8 |
value[2] << 16;
}
else
{
valueInt = value[0] << 16 |
value[1] << 8 |
value[2];
}
// Deserialize value
return (Int24)ApplyBitMask(valueInt);
}
private static void ValidateNumericRange(int value)
{
if (value > (MaxValue32 + 1) || value < MinValue32)
throw new OverflowException(string.Format("Value of {0} will not fit in a 24-bit signed integer", value));
}
private static int ApplyBitMask(int value)
{
// Check bit 23, the sign bit in a signed 24-bit integer
if ((value & 0x00800000) > 0)
{
// If the sign-bit is set, this number will be negative - set all high-byte bits (keeps 32-bit number in 24-bit range)
value |= BitMask;
}
else
{
// If the sign-bit is not set, this number will be positive - clear all high-byte bits (keeps 32-bit number in 24-bit range)
value &= ~BitMask;
}
return value;
}
#endregion
}
}