Beispiel #1
0
        public void TestDivide()
        {
            var fr = new RandomGenerator();

            for (var i = 0; i < 500; ++i)
            {
                ERational er  = RandomObjects.RandomERational(fr);
                ERational er2 = RandomObjects.RandomERational(fr);
                if (er2.IsZero || !er2.IsFinite)
                {
                    continue;
                }
                if (er.IsZero || !er.IsFinite)
                {
                    continue;
                }
                ERational ermult = er.Multiply(er2);
                ERational erdiv  = ermult.Divide(er);
                TestCommon.CompareTestEqual(erdiv, er2);
                erdiv = ermult.Divide(er2);
                TestCommon.CompareTestEqual(erdiv, er);
            }
        }
Beispiel #2
0
        public void TestRemainder()
        {
            var fr = new RandomGenerator();

            for (var i = 0; i < 100; ++i)
            {
                ERational er;
                ERational er2;
                er = ERational.Create(
                    RandomObjects.RandomEInteger(fr),
                    EInteger.One);
                er2 = ERational.Create(
                    RandomObjects.RandomEInteger(fr),
                    EInteger.One);
                if (er2.IsZero || !er2.IsFinite)
                {
                    continue;
                }
                if (er.IsZero || !er.IsFinite)
                {
                    // Code below will divide by "er",
                    // so skip if "er" is zero
                    continue;
                }
                ERational ermult = er.Multiply(er2);
                ERational erdiv  = ermult.Divide(er);
                erdiv = ermult.Remainder(er);
                if (!erdiv.IsZero)
                {
                    Assert.Fail(ermult + "; " + er);
                }
                erdiv = ermult.Remainder(er2);
                if (!erdiv.IsZero)
                {
                    Assert.Fail(er + "; " + er2);
                }
            }
        }
Beispiel #3
0
        public static CBORObject Divide(CBORObject a, CBORObject b)
        {
            if (a == null)
            {
                throw new ArgumentNullException("a");
            }
            if (b == null)
            {
                throw new ArgumentNullException("b");
            }
            if (a.Type != CBORType.Number)
            {
                throw new ArgumentException("a.Type (" + a.Type +
                                            ") is not equal to " + CBORType.Number);
            }
            if (b.Type != CBORType.Number)
            {
                throw new ArgumentException("b.Type (" + b.Type +
                                            ") is not equal to " + CBORType.Number);
            }
            object objA  = a.ThisItem;
            object objB  = b.ThisItem;
            int    typeA = a.ItemType;
            int    typeB = b.ItemType;

            if (typeA == CBORObject.CBORObjectTypeInteger && typeB ==
                CBORObject.CBORObjectTypeInteger)
            {
                var valueA = (long)objA;
                var valueB = (long)objB;
                if (valueB == 0)
                {
                    return((valueA == 0) ? CBORObject.NaN : ((valueA < 0) ?
                                                             CBORObject.NegativeInfinity : CBORObject.PositiveInfinity));
                }
                if (valueA == Int64.MinValue && valueB == -1)
                {
                    return(CBORObject.FromObject(valueA).Negate());
                }
                long quo = valueA / valueB;
                long rem = valueA - (quo * valueB);
                return((rem == 0) ? CBORObject.FromObject(quo) :
                       CBORObject.FromObject(
                           ERational.Create(
                               (EInteger)valueA,
                               (EInteger)valueB)));
            }
            if (typeA == CBORObject.CBORObjectTypeExtendedRational ||
                typeB == CBORObject.CBORObjectTypeExtendedRational)
            {
                ERational e1 =
                    CBORObject.GetNumberInterface(typeA).AsExtendedRational(objA);
                ERational e2 =
                    CBORObject.GetNumberInterface(typeB).AsExtendedRational(objB);
                return(CBORObject.FromObject(e1.Divide(e2)));
            }
            if (typeA == CBORObject.CBORObjectTypeExtendedDecimal ||
                typeB == CBORObject.CBORObjectTypeExtendedDecimal)
            {
                EDecimal e1 =
                    CBORObject.GetNumberInterface(typeA).AsExtendedDecimal(objA);
                EDecimal e2 =
                    CBORObject.GetNumberInterface(typeB).AsExtendedDecimal(objB);
                if (e1.IsZero && e2.IsZero)
                {
                    return(CBORObject.NaN);
                }
                EDecimal eret = e1.Divide(e2, null);
                // If either operand is infinity or NaN, the result
                // is already exact. Likewise if the result is a finite number.
                if (!e1.IsFinite || !e2.IsFinite || eret.IsFinite)
                {
                    return(CBORObject.FromObject(eret));
                }
                ERational er1 =
                    CBORObject.GetNumberInterface(typeA).AsExtendedRational(objA);
                ERational er2 =
                    CBORObject.GetNumberInterface(typeB).AsExtendedRational(objB);
                return(CBORObject.FromObject(er1.Divide(er2)));
            }
            if (typeA == CBORObject.CBORObjectTypeExtendedFloat || typeB ==
                CBORObject.CBORObjectTypeExtendedFloat ||
                typeA == CBORObject.CBORObjectTypeDouble || typeB ==
                CBORObject.CBORObjectTypeDouble ||
                typeA == CBORObject.CBORObjectTypeSingle || typeB ==
                CBORObject.CBORObjectTypeSingle)
            {
                EFloat e1 =
                    CBORObject.GetNumberInterface(typeA).AsExtendedFloat(objA);
                EFloat e2 = CBORObject.GetNumberInterface(typeB).AsExtendedFloat(objB);
                if (e1.IsZero && e2.IsZero)
                {
                    return(CBORObject.NaN);
                }
                EFloat eret = e1.Divide(e2, null);
                // If either operand is infinity or NaN, the result
                // is already exact. Likewise if the result is a finite number.
                if (!e1.IsFinite || !e2.IsFinite || eret.IsFinite)
                {
                    return(CBORObject.FromObject(eret));
                }
                ERational er1 =
                    CBORObject.GetNumberInterface(typeA).AsExtendedRational(objA);
                ERational er2 =
                    CBORObject.GetNumberInterface(typeB).AsExtendedRational(objB);
                return(CBORObject.FromObject(er1.Divide(er2)));
            }
            else
            {
                EInteger b1 = CBORObject.GetNumberInterface(typeA).AsEInteger(objA);
                EInteger b2 = CBORObject.GetNumberInterface(typeB).AsEInteger(objB);
                if (b2.IsZero)
                {
                    return(b1.IsZero ? CBORObject.NaN : ((b1.Sign < 0) ?
                                                         CBORObject.NegativeInfinity : CBORObject.PositiveInfinity));
                }
                EInteger bigrem;
                EInteger bigquo;
                {
                    EInteger[] divrem = b1.DivRem(b2);
                    bigquo = divrem[0];
                    bigrem = divrem[1];
                }
                return(bigrem.IsZero ? CBORObject.FromObject(bigquo) :
                       CBORObject.FromObject(ERational.Create(b1, b2)));
            }
        }
Beispiel #4
0
        /// <summary>Returns the quotient of this number and another
        /// number.</summary>
        /// <param name='b'>The right-hand side (divisor) to the division
        /// operation.</param>
        /// <returns>The quotient of this number and another one.</returns>
        /// <exception cref='ArgumentNullException'>The parameter <paramref
        /// name='b'/> is null.</exception>
        public CBORNumber Divide(CBORNumber b)
        {
            if (b == null)
            {
                throw new ArgumentNullException(nameof(b));
            }
            CBORNumber a     = this;
            object     objA  = a.value;
            object     objB  = b.value;
            Kind       typeA = a.kind;
            Kind       typeB = b.kind;

            if (typeA == Kind.Integer && typeB == Kind.Integer)
            {
                var valueA = (long)objA;
                var valueB = (long)objB;
                if (valueB == 0)
                {
                    return((valueA == 0) ? CBORNumber.FromObject(EDecimal.NaN) :
                           ((valueA < 0) ?
                            CBORNumber.FromObject(EDecimal.NegativeInfinity) :
                            CBORNumber.FromObject(EDecimal.PositiveInfinity)));
                }
                if (valueA == Int64.MinValue && valueB == -1)
                {
                    return(new CBORNumber(Kind.Integer, valueA).Negate());
                }
                long quo = valueA / valueB;
                long rem = valueA - (quo * valueB);
                return((rem == 0) ? new CBORNumber(Kind.Integer, quo) :
                       new CBORNumber(Kind.ERational,
                                      ERational.Create(
                                          (EInteger)valueA,
                                          (EInteger)valueB)));
            }
            if (typeA == Kind.ERational || typeB == Kind.ERational)
            {
                ERational e1 = GetNumberInterface(typeA).AsExtendedRational(objA);
                ERational e2 = GetNumberInterface(typeB).AsExtendedRational(objB);
                return(new CBORNumber(Kind.ERational, e1.Divide(e2)));
            }
            if (typeA == Kind.EDecimal ||
                typeB == Kind.EDecimal)
            {
                EDecimal e1 =
                    GetNumberInterface(typeA).AsExtendedDecimal(objA);
                EDecimal e2 = GetNumberInterface(typeB).AsExtendedDecimal(objB);
                if (e1.IsZero && e2.IsZero)
                {
                    return(new CBORNumber(Kind.EDecimal, EDecimal.NaN));
                }
                EDecimal eret = e1.Divide(e2, null);
                // If either operand is infinity or NaN, the result
                // is already exact. Likewise if the result is a finite number.
                if (!e1.IsFinite || !e2.IsFinite || eret.IsFinite)
                {
                    return(new CBORNumber(Kind.EDecimal, eret));
                }
                ERational er1 = GetNumberInterface(typeA).AsExtendedRational(objA);
                ERational er2 = GetNumberInterface(typeB).AsExtendedRational(objB);
                return(new CBORNumber(Kind.ERational, er1.Divide(er2)));
            }
            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);
                if (e1.IsZero && e2.IsZero)
                {
                    return(CBORNumber.FromObject(EDecimal.NaN));
                }
                EFloat eret = e1.Divide(e2, null);
                // If either operand is infinity or NaN, the result
                // is already exact. Likewise if the result is a finite number.
                if (!e1.IsFinite || !e2.IsFinite || eret.IsFinite)
                {
                    return(CBORNumber.FromObject(eret));
                }
                ERational er1 = GetNumberInterface(typeA).AsExtendedRational(objA);
                ERational er2 = GetNumberInterface(typeB).AsExtendedRational(objB);
                return(new CBORNumber(Kind.ERational, er1.Divide(er2)));
            }
            else
            {
                EInteger b1 = GetNumberInterface(typeA).AsEInteger(objA);
                EInteger b2 = GetNumberInterface(typeB).AsEInteger(objB);
                if (b2.IsZero)
                {
                    return(b1.IsZero ? CBORNumber.FromObject(EDecimal.NaN) : ((b1.Sign <
                                                                               0) ?
                                                                              CBORNumber.FromObject(EDecimal.NegativeInfinity) :
                                                                              CBORNumber.FromObject(EDecimal.PositiveInfinity)));
                }
                EInteger bigrem;
                EInteger bigquo;
                {
                    EInteger[] divrem = b1.DivRem(b2);
                    bigquo = divrem[0];
                    bigrem = divrem[1];
                }
                return(bigrem.IsZero ? CBORNumber.FromObject(bigquo) :
                       new CBORNumber(Kind.ERational, ERational.Create(b1, b2)));
            }
        }