Number calculation utils : Number « Data Types « C# / C Sharp






Number calculation utils

   
#region License

/*
 * Copyright  2002-2005 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#endregion

#region Imports

using System;
using System.ComponentModel;

#endregion

namespace Spring.Util
{
    /// <summary>
    /// Various utility methods relating to numbers.
    /// </summary>
    /// <remarks>
    /// <p>
    /// Mainly for internal use within the framework.
    /// </p>
    /// </remarks>
    /// <author>Aleksandar Seovic</author>
    public sealed class NumberUtils
    {
        /// <summary>
        /// Determines whether the supplied <paramref name="number"/> is an integer.
        /// </summary>
        /// <param name="number">The object to check.</param>
        /// <returns>
        /// <see lang="true"/> if the supplied <paramref name="number"/> is an integer.
        /// </returns>
        public static bool IsInteger(object number)
        {
            return (number is Int32 || number is Int16 || number is Int64 || number is UInt32
                || number is UInt16 || number is UInt64 || number is Byte || number is SByte);
        }

        /// <summary>
        /// Determines whether the supplied <paramref name="number"/> is a decimal number.
        /// </summary>
        /// <param name="number">The object to check.</param>
        /// <returns>
        /// <see lang="true"/> if the supplied <paramref name="number"/> is a decimal number.
        /// </returns>
        public static bool IsDecimal(object number)
        {

            return (number is Single || number is Double || number is Decimal);
        }

        /// <summary>
        /// Determines whether the supplied <paramref name="number"/> is of numeric type.
        /// </summary>
        /// <param name="number">The object to check.</param>
        /// <returns>
        ///   <c>true</c> if the specified object is of numeric type; otherwise, <c>false</c>.
        /// </returns>
        public static bool IsNumber(object number)
        {
            return (IsInteger(number) || IsDecimal(number));
        }

        /// <summary>
        /// Determines whether the supplied <paramref name="number"/> can be converted to an integer.
        /// </summary>
        /// <param name="number">The object to check.</param>
        /// <returns>
        /// <see lang="true"/> if the supplied <paramref name="number"/> can be converted to an integer.
        /// </returns>
        public static bool CanConvertToInteger(object number)
        {
            TypeConverter converter = TypeDescriptor.GetConverter(number);
            return (converter.CanConvertTo(typeof(Int32))
                || converter.CanConvertTo(typeof(Int16))
                || converter.CanConvertTo(typeof(Int64))
                || converter.CanConvertTo(typeof(UInt16))
                || converter.CanConvertTo(typeof(UInt64))
                || converter.CanConvertTo(typeof(Byte))
                || converter.CanConvertTo(typeof(SByte))
                   );
        }

        /// <summary>
        /// Determines whether the supplied <paramref name="number"/> can be converted to an integer.
        /// </summary>
        /// <param name="number">The object to check.</param>
        /// <returns>
        /// <see lang="true"/> if the supplied <paramref name="number"/> can be converted to an integer.
        /// </returns>
        public static bool CanConvertToDecimal(object number)
        {
            TypeConverter converter = TypeDescriptor.GetConverter(number);
            return (converter.CanConvertTo(typeof(Single))
                || converter.CanConvertTo(typeof(Double))
                || converter.CanConvertTo(typeof(Decimal))
                   );
        }

        /// <summary>
        /// Determines whether the supplied <paramref name="number"/> can be converted to a number.
        /// </summary>
        /// <param name="number">The object to check.</param>
        /// <returns>
        ///   <c>true</c> if the specified object is decimal number; otherwise, <c>false</c>.
        /// </returns>
        public static bool CanConvertToNumber(object number)
        {
            return (CanConvertToInteger(number) || CanConvertToDecimal(number));
        }

        /// <summary>
        /// Is the supplied <paramref name="number"/> equal to zero (0)?
        /// </summary>
        /// <param name="number">The number to check.</param>
        /// <returns>
        /// <see lang="true"/> id the supplied <paramref name="number"/> is equal to zero (0).
        /// </returns>
        public static bool IsZero(object number)
        {
            if (number is Int32)
                return ((Int32)number) == 0;
            else if (number is Int16)
                return ((Int16)number) == 0;
            else if (number is Int64)
                return ((Int64)number) == 0;
            else if (number is UInt16)
                return ((Int32)number) == 0;
            else if (number is UInt32)
                return ((Int64)number) == 0;
            else if (number is UInt64)
                return (Convert.ToDecimal(number) == 0);
            else if (number is Byte)
                return ((Int16)number) == 0;
            else if (number is SByte)
                return ((Int16)number) == 0;
            else if (number is Single)
                return ((Single)number) == 0f;
            else if (number is Double)
                return ((Double)number) == 0d;
            else if (number is Decimal)
                return ((Decimal)number) == 0m;
            return false;
        }

        /// <summary>
        /// Negates the supplied <paramref name="number"/>.
        /// </summary>
        /// <param name="number">The number to negate.</param>
        /// <returns>The supplied <paramref name="number"/> negated.</returns>
        /// <exception cref="System.ArgumentException">
        /// If the supplied <paramref name="number"/> is not a supported numeric type.
        /// </exception>
        public static object Negate(object number)
        {
            if (number is Int32)
                return -((Int32)number);
            else if (number is Int16)
                return -((Int16)number);
            else if (number is Int64)
                return -((Int64)number);
            else if (number is UInt16)
                return -((Int32)number);
            else if (number is UInt32)
                return -((Int64)number);
            else if (number is UInt64)
                return -(Convert.ToDecimal(number));
            else if (number is Byte)
                return -((Int16)number);
            else if (number is SByte)
                return -((Int16)number);
            else if (number is Single)
                return -((Single)number);
            else if (number is Double)
                return -((Double)number);
            else if (number is Decimal)
                return -((Decimal)number);
            else
            {
                throw new ArgumentException(string.Format("'{0}' is not one of the supported numeric types.", number));
            }
        }

        /// <summary>
        /// Returns the bitwise not (~) of the supplied <paramref name="number"/>.
        /// </summary>
        /// <param name="number">The number.</param>
        /// <returns>The value of ~<paramref name="number"/>.</returns>
        /// <exception cref="System.ArgumentException">
        /// If the supplied <paramref name="number"/> is not a supported numeric type.
        /// </exception>
        public static object BitwiseNot(object number)
        {
            if (number is bool)
                return !((bool)number);
            else if (number is Int32)
                return ~((Int32)number);
            else if (number is Int16)
                return ~((Int16)number);
            else if (number is Int64)
                return ~((Int64)number);
            else if (number is UInt16)
                return ~((UInt16)number);
            else if (number is UInt32)
                return ~((UInt32)number);
            else if (number is UInt64)
                return ~((UInt64)number);
            else if (number is Byte)
                return ~((Byte)number);
            else if (number is SByte)
                return ~((SByte)number);
            else
            {
                throw new ArgumentException(string.Format("'{0}' is not one of the supported integer types.", number));
            }
        }

        /// <summary>
        /// Bitwise ANDs (&amp;) the specified integral values.
        /// </summary>
        /// <param name="m">The first number.</param>
        /// <param name="n">The second number.</param>
        /// <exception cref="System.ArgumentException">
        /// If one of the supplied arguments is not a supported integral types.
        /// </exception>
        public static object BitwiseAnd(object m, object n)
        {
            CoerceTypes(ref m, ref n);

            if (n is bool)
                return (bool)m & (bool)n;
            else if (n is Int32)
                return (Int32)m & (Int32)n;
            else if (n is Int16)
                return (Int16)m & (Int16)n;
            else if (n is Int64)
                return (Int64)m & (Int64)n;
            else if (n is UInt16)
                return (UInt16)m & (UInt16)n;
            else if (n is UInt32)
                return (UInt32)m & (UInt32)n;
            else if (n is UInt64)
                return (UInt64)m & (UInt64)n;
            else if (n is Byte)
                return (Byte)m & (Byte)n;
            else if (n is SByte)
                return (SByte)m & (SByte)n;
            else
            {
                throw new ArgumentException(string.Format("'{0}' and/or '{1}' are not one of the supported integral types.", m, n));
            }
        }

        /// <summary>
        /// Bitwise ORs (|) the specified integral values.
        /// </summary>
        /// <param name="m">The first number.</param>
        /// <param name="n">The second number.</param>
        /// <exception cref="System.ArgumentException">
        /// If one of the supplied arguments is not a supported integral types.
        /// </exception>
        public static object BitwiseOr(object m, object n)
        {
            CoerceTypes(ref m, ref n);

            if (n is bool)
                return (bool)m | (bool)n;
            else if (n is Int32)
                return (Int32)m | (Int32)n;
#if NET_2_0
            else if (n is Int16)
                return (Int16)m | (Int16)n;
#endif
            else if (n is Int64)
                return (Int64)m | (Int64)n;
            else if (n is UInt16)
                return (UInt16)m | (UInt16)n;
            else if (n is UInt32)
                return (UInt32)m | (UInt32)n;
            else if (n is UInt64)
                return (UInt64)m | (UInt64)n;
            else if (n is Byte)
                return (Byte)m | (Byte)n;
#if NET_2_0
            else if (n is SByte)
            {
                if (SystemUtils.MonoRuntime)
                {
                    SByte x = (sbyte) n;
                    SByte y = (sbyte) m;
                    int result = (int) x | (int) y;
                    return SByte.Parse(result.ToString());
                }
                return (SByte) ((SByte) m | (SByte) n);
            }
#endif
            throw new ArgumentException(string.Format("'{0}' and/or '{1}' are not one of the supported integral types.", m, n));
        }

        /// <summary>
        /// Bitwise XORs (^) the specified integral values.
        /// </summary>
        /// <param name="m">The first number.</param>
        /// <param name="n">The second number.</param>
        /// <exception cref="System.ArgumentException">
        /// If one of the supplied arguments is not a supported integral types.
        /// </exception>
        public static object BitwiseXor(object m, object n)
        {
            CoerceTypes(ref m, ref n);

            if (n is bool)
                return (bool)m ^ (bool)n;
            else if (n is Int32)
                return (Int32)m ^ (Int32)n;
            else if (n is Int16)
                return (Int16)m ^ (Int16)n;
            else if (n is Int64)
                return (Int64)m ^ (Int64)n;
            else if (n is UInt16)
                return (UInt16)m ^ (UInt16)n;
            else if (n is UInt32)
                return (UInt32)m ^ (UInt32)n;
            else if (n is UInt64)
                return (UInt64)m ^ (UInt64)n;
            else if (n is Byte)
                return (Byte)m ^ (Byte)n;
            else if (n is SByte)
                return (SByte)m ^ (SByte)n;
            else
            {
                throw new ArgumentException(string.Format("'{0}' and/or '{1}' are not one of the supported integral types.", m, n));
            }
        }

        /// <summary>
        /// Adds the specified numbers.
        /// </summary>
        /// <param name="m">The first number.</param>
        /// <param name="n">The second number.</param>
        public static object Add(object m, object n)
        {
            CoerceTypes(ref m, ref n);

            if (n is Int32)
                return (Int32)m + (Int32)n;
            else if (n is Int16)
                return (Int16)m + (Int16)n;
            else if (n is Int64)
                return (Int64)m + (Int64)n;
            else if (n is UInt16)
                return (UInt16)m + (UInt16)n;
            else if (n is UInt32)
                return (UInt32)m + (UInt32)n;
            else if (n is UInt64)
                return (UInt64)m + (UInt64)n;
            else if (n is Byte)
                return (Byte)m + (Byte)n;
            else if (n is SByte)
                return (SByte)m + (SByte)n;
            else if (n is Single)
                return (Single)m + (Single)n;
            else if (n is Double)
                return (Double)m + (Double)n;
            else if (n is Decimal)
                return (Decimal)m + (Decimal)n;
            else
            {
                throw new ArgumentException(string.Format("'{0}' and/or '{1}' are not one of the supported numeric types.", m, n));
            }
        }

        /// <summary>
        /// Subtracts the specified numbers.
        /// </summary>
        /// <param name="m">The first number.</param>
        /// <param name="n">The second number.</param>
        public static object Subtract(object m, object n)
        {
            CoerceTypes(ref m, ref n);

            if (n is Int32)
                return (Int32)m - (Int32)n;
            else if (n is Int16)
                return (Int16)m - (Int16)n;
            else if (n is Int64)
                return (Int64)m - (Int64)n;
            else if (n is UInt16)
                return (UInt16)m - (UInt16)n;
            else if (n is UInt32)
                return (UInt32)m - (UInt32)n;
            else if (n is UInt64)
                return (UInt64)m - (UInt64)n;
            else if (n is Byte)
                return (Byte)m - (Byte)n;
            else if (n is SByte)
                return (SByte)m - (SByte)n;
            else if (n is Single)
                return (Single)m - (Single)n;
            else if (n is Double)
                return (Double)m - (Double)n;
            else if (n is Decimal)
                return (Decimal)m - (Decimal)n;
            else
            {
                throw new ArgumentException(string.Format("'{0}' and/or '{1}' are not one of the supported numeric types.", m, n));
            }
        }

        /// <summary>
        /// Multiplies the specified numbers.
        /// </summary>
        /// <param name="m">The first number.</param>
        /// <param name="n">The second number.</param>
        public static object Multiply(object m, object n)
        {
            CoerceTypes(ref m, ref n);

            if (n is Int32)
                return (Int32)m * (Int32)n;
            else if (n is Int16)
                return (Int16)m * (Int16)n;
            else if (n is Int64)
                return (Int64)m * (Int64)n;
            else if (n is UInt16)
                return (UInt16)m * (UInt16)n;
            else if (n is UInt32)
                return (UInt32)m * (UInt32)n;
            else if (n is UInt64)
                return (UInt64)m * (UInt64)n;
            else if (n is Byte)
                return (Byte)m * (Byte)n;
            else if (n is SByte)
                return (SByte)m * (SByte)n;
            else if (n is Single)
                return (Single)m * (Single)n;
            else if (n is Double)
                return (Double)m * (Double)n;
            else if (n is Decimal)
                return (Decimal)m * (Decimal)n;
            else
            {
                throw new ArgumentException(string.Format("'{0}' and/or '{1}' are not one of the supported numeric types.", m, n));
            }
        }

        /// <summary>
        /// Divides the specified numbers.
        /// </summary>
        /// <param name="m">The first number.</param>
        /// <param name="n">The second number.</param>
        public static object Divide(object m, object n)
        {
            CoerceTypes(ref m, ref n);

            if (n is Int32)
                return (Int32)m / (Int32)n;
            else if (n is Int16)
                return (Int16)m / (Int16)n;
            else if (n is Int64)
                return (Int64)m / (Int64)n;
            else if (n is UInt16)
                return (UInt16)m / (UInt16)n;
            else if (n is UInt32)
                return (UInt32)m / (UInt32)n;
            else if (n is UInt64)
                return (UInt64)m / (UInt64)n;
            else if (n is Byte)
                return (Byte)m / (Byte)n;
            else if (n is SByte)
                return (SByte)m / (SByte)n;
            else if (n is Single)
                return (Single)m / (Single)n;
            else if (n is Double)
                return (Double)m / (Double)n;
            else if (n is Decimal)
                return (Decimal)m / (Decimal)n;
            else
            {
                throw new ArgumentException(string.Format("'{0}' and/or '{1}' are not one of the supported numeric types.", m, n));
            }
        }

        /// <summary>
        /// Calculates remainder for the specified numbers.
        /// </summary>
        /// <param name="m">The first number (dividend).</param>
        /// <param name="n">The second number (divisor).</param>
        public static object Modulus(object m, object n)
        {
            CoerceTypes(ref m, ref n);

            if (n is Int32)
                return (Int32)m % (Int32)n;
            else if (n is Int16)
                return (Int16)m % (Int16)n;
            else if (n is Int64)
                return (Int64)m % (Int64)n;
            else if (n is UInt16)
                return (UInt16)m % (UInt16)n;
            else if (n is UInt32)
                return (UInt32)m % (UInt32)n;
            else if (n is UInt64)
                return (UInt64)m % (UInt64)n;
            else if (n is Byte)
                return (Byte)m % (Byte)n;
            else if (n is SByte)
                return (SByte)m % (SByte)n;
            else if (n is Single)
                return (Single)m % (Single)n;
            else if (n is Double)
                return (Double)m % (Double)n;
            else if (n is Decimal)
                return (Decimal)m % (Decimal)n;
            else
            {
                throw new ArgumentException(string.Format("'{0}' and/or '{1}' are not one of the supported numeric types.", m, n));
            }
        }

        /// <summary>
        /// Raises first number to the power of the second one.
        /// </summary>
        /// <param name="m">The first number.</param>
        /// <param name="n">The second number.</param>
        public static object Power(object m, object n)
        {
            return Math.Pow(Convert.ToDouble(m), Convert.ToDouble(n));
        }

        /// <summary>
        /// Coerces the types so they can be compared.
        /// </summary>
        /// <param name="m">The right.</param>
        /// <param name="n">The left.</param>
        public static void CoerceTypes(ref object m, ref object n)
        {
            TypeCode leftTypeCode = Convert.GetTypeCode(m);
            TypeCode rightTypeCode = Convert.GetTypeCode(n);

            if (leftTypeCode > rightTypeCode)
            {
                n = Convert.ChangeType(n, leftTypeCode);
            }
            else
            {
                m = Convert.ChangeType(m, rightTypeCode);
            }
        }

        #region Constructor (s) / Destructor

        // CLOVER:OFF

        /// <summary>
        /// Creates a new instance of the <see cref="Spring.Util.NumberUtils"/> class.
        /// </summary>
        /// <remarks>
        /// <p>
        /// This is a utility class, and as such exposes no public constructors.
        /// </p>
        /// </remarks>
        private NumberUtils()
        {
        }

        // CLOVER:ON

        #endregion
    }
}

   
    
    
  








Related examples in the same category

1.Converting Degrees to RadiansConverting Degrees to Radians
2.Converting Radians to DegreesConverting Radians to Degrees
3.Converting a Number in Another Base to Base10Converting a Number in Another Base to Base10
4.Determining if a String is a Valid Number by Parse functionsDetermining if a String is a Valid Number by Parse functions
5.Use regualr expression to check: is it a numberUse regualr expression to check: is it a number
6.Use int.Parse to check: is it an integerUse int.Parse to check: is it an integer
7.Use Integer.Parse to check: is it a numberUse Integer.Parse to check: is it a number
8.Use regualr expression to check: Is it an Unsigned IntegerUse regualr expression to check: Is it an Unsigned Integer
9.Use regular expression to get number from stringUse regular expression to get number from string
10.Faster way to get number from stringFaster way to get number from string
11.Converting Celsius to FahrenheitConverting Celsius to Fahrenheit
12.Converting Fahrenheit to CelsiusConverting Fahrenheit to Celsius
13.Is it a double numberIs it a double number
14.Test for an Even or Odd ValueTest for an Even or Odd Value
15.System maximums and minimumsSystem maximums and minimums
16.Declare int and use itDeclare int and use it
17.Use int variableUse int variable
18.shows that using an instance of the System.Int32 stucture is the same as using the int keywordshows that using an instance of the System.Int32 stucture is the same as using the int keyword
19.Numeric Parsing DemoNumeric Parsing Demo
20.Double Range
21.Int Range
22.Sparse Double Range
23.Sparse Int Range
24.Checks if a value is in a range (inclusive)
25.Determines whether the specified value is null.
26.Converts specified value to nullable value.
27.Validate number
28.Native SizeOf
29.Is Numeric