Beispiel #1
0
        public void MathComparisonTest()
        {
            var r = new ERational(142342, 432);
            var f = EFloat.FromString("1.5", null);

            Console.WriteLine("{0}, {1}", r, f);
            Assert.IsTrue(r.CompareToBinary(f) > 0);
        }
Beispiel #2
0
        /// <summary>Compares two CBOR numbers. In this implementation, the two
        /// numbers' mathematical values are compared. Here, NaN (not-a-number)
        /// is considered greater than any number.</summary>
        /// <param name='other'>A value to compare with. Can be null.</param>
        /// <returns>A negative number, if this value is less than the other
        /// object; or 0, if both values are equal; or a positive number, if
        /// this value is less than the other object or if the other object is
        /// null.
        /// <para>This implementation returns a positive number if <paramref
        /// name='other'/> is null, to conform to the.NET definition of
        /// CompareTo. This is the case even in the Java version of this
        /// library, for consistency's sake, even though implementations of
        /// <c>Comparable.compareTo()</c> in Java ought to throw an exception
        /// if they receive a null argument rather than treating null as less
        /// or greater than any object.</para>.</returns>
        public int CompareTo(CBORNumber other)
        {
            if (other == null)
            {
                return(1);
            }
            if (this == other)
            {
                return(0);
            }
            var    cmp   = 0;
            Kind   typeA = this.kind;
            Kind   typeB = other.kind;
            object objA  = this.value;
            object objB  = other.value;

            if (typeA == typeB)
            {
                switch (typeA)
                {
                case Kind.Integer: {
                    var a = (long)objA;
                    var b = (long)objB;
                    cmp = (a == b) ? 0 : ((a < b) ? -1 : 1);
                    break;
                }

                case Kind.EInteger: {
                    var bigintA = (EInteger)objA;
                    var bigintB = (EInteger)objB;
                    cmp = bigintA.CompareTo(bigintB);
                    break;
                }

                case Kind.Double: {
                    var a = (double)objA;
                    var b = (double)objB;
                    // Treat NaN as greater than all other numbers
                    cmp = Double.IsNaN(a) ? (Double.IsNaN(b) ? 0 : 1) :
                          (Double.IsNaN(b) ? (-1) : ((a == b) ? 0 : ((a < b) ? -1 :
                                                                     1)));
                    break;
                }

                case Kind.EDecimal: {
                    cmp = ((EDecimal)objA).CompareTo((EDecimal)objB);
                    break;
                }

                case Kind.EFloat: {
                    cmp = ((EFloat)objA).CompareTo(
                        (EFloat)objB);
                    break;
                }

                case Kind.ERational: {
                    cmp = ((ERational)objA).CompareTo(
                        (ERational)objB);
                    break;
                }

                default: throw new InvalidOperationException("Unexpected data type");
                }
            }
            else
            {
                int s1 = GetNumberInterface(typeA).Sign(objA);
                int s2 = GetNumberInterface(typeB).Sign(objB);
                if (s1 != s2 && s1 != 2 && s2 != 2)
                {
                    // if both types are numbers
                    // and their signs are different
                    return((s1 < s2) ? -1 : 1);
                }
                if (s1 == 2 && s2 == 2)
                {
                    // both are NaN
                    cmp = 0;
                }
                else if (s1 == 2)
                {
                    // first object is NaN
                    return(1);
                }
                else if (s2 == 2)
                {
                    // second object is NaN
                    return(-1);
                }
                else
                {
                    // DebugUtility.Log("a=" + this + " b=" + other);
                    if (typeA == Kind.ERational)
                    {
                        ERational e1 =
                            GetNumberInterface(typeA).AsExtendedRational(objA);
                        if (typeB == Kind.EDecimal)
                        {
                            EDecimal e2 =
                                GetNumberInterface(typeB).AsExtendedDecimal(objB);
                            cmp = e1.CompareToDecimal(e2);
                        }
                        else
                        {
                            EFloat e2 = GetNumberInterface(typeB).AsExtendedFloat(objB);
                            cmp = e1.CompareToBinary(e2);
                        }
                    }
                    else if (typeB == Kind.ERational)
                    {
                        ERational e2 =
                            GetNumberInterface(typeB).AsExtendedRational(objB);
                        if (typeA == Kind.EDecimal)
                        {
                            EDecimal e1 =
                                GetNumberInterface(typeA).AsExtendedDecimal(objA);
                            cmp = e2.CompareToDecimal(e1);
                            cmp = -cmp;
                        }
                        else
                        {
                            EFloat e1 =
                                GetNumberInterface(typeA).AsExtendedFloat(objA);
                            cmp = e2.CompareToBinary(e1);
                            cmp = -cmp;
                        }
                    }
                    else if (typeA == Kind.EDecimal ||
                             typeB == Kind.EDecimal)
                    {
                        EDecimal e1 = null;
                        EDecimal e2 = null;
                        if (typeA == Kind.EFloat)
                        {
                            var ef1 = (EFloat)objA;
                            e2  = (EDecimal)objB;
                            cmp = e2.CompareToBinary(ef1);
                            cmp = -cmp;
                        }
                        else if (typeB == Kind.EFloat)
                        {
                            var ef1 = (EFloat)objB;
                            e2  = (EDecimal)objA;
                            cmp = e2.CompareToBinary(ef1);
                        }
                        else
                        {
                            e1  = GetNumberInterface(typeA).AsExtendedDecimal(objA);
                            e2  = GetNumberInterface(typeB).AsExtendedDecimal(objB);
                            cmp = e1.CompareTo(e2);
                        }
                    }
                    else if (typeA == Kind.EFloat || typeB ==
                             Kind.EFloat || typeA == Kind.Double || typeB ==
                             Kind.Double)
                    {
                        EFloat e1 =
                            GetNumberInterface(typeA).AsExtendedFloat(objA);
                        EFloat e2 = GetNumberInterface(typeB).AsExtendedFloat(objB);
                        cmp = e1.CompareTo(e2);
                    }
                    else
                    {
                        EInteger b1 = GetNumberInterface(typeA).AsEInteger(objA);
                        EInteger b2 = GetNumberInterface(typeB).AsEInteger(objB);
                        cmp = b1.CompareTo(b2);
                    }
                }
            }
            return(cmp);
        }