Beispiel #1
0
        public CBORObject ValidateObject(CBORObject obj)
        {
            if (obj.Type != CBORType.Array)
            {
                throw new CBORException("Rational number must be an array");
            }
            if (obj.Count != 2)
            {
                throw new CBORException("Rational number requires exactly 2 items");
            }
            CBORObject first  = obj[0];
            CBORObject second = obj[1];

            if (!first.IsIntegral)
            {
                throw new CBORException("Rational number requires integer numerator");
            }
            if (!second.IsIntegral)
            {
                throw new CBORException("Rational number requires integer denominator");
            }
            if (second.Sign <= 0)
            {
                throw new CBORException("Rational number requires denominator greater than 0");
            }
            EInteger denom = second.AsEInteger();

            // NOTE: Discards tags. See comment in CBORTag2.
            return(denom.Equals(EInteger.One) ?
                   CBORObject.FromObject(first.AsEInteger()) :
                   CBORObject.FromObject(
                       ERational.Create(
                           first.AsEInteger(),
                           denom)));
        }
 /// <include file='../docs.xml'
 /// path='docs/doc[@name="M:PeterO.ExtendedRational.Create(System.Int32,System.Int32)"]/*'/>
 public static ExtendedRational Create(
     int numeratorSmall,
     int denominatorSmall)
 {
     return(new ExtendedRational(
                ERational.Create(
                    numeratorSmall,
                    denominatorSmall)));
 }
Beispiel #3
0
        public void TestCompareTo()
        {
            var r = new RandomGenerator();

            for (var i = 0; i < 500; ++i)
            {
                ERational bigintA = RandomObjects.RandomERational(r);
                ERational bigintB = RandomObjects.RandomERational(r);
                ERational bigintC = RandomObjects.RandomERational(r);
                TestCommon.CompareTestRelations(bigintA, bigintB, bigintC);
            }
            TestCommon.CompareTestLess(ERational.Zero, ERational.NaN);
            ERational rat, rat2;

            for (var i = 0; i < 100; ++i)
            {
                EInteger num = RandomObjects.RandomEInteger(r);
                if (num.IsZero)
                {
                    // Skip if number is 0; 0/1 and 0/2 are
                    // equal in that case
                    continue;
                }
                num  = num.Abs();
                rat  = ERational.Create(num, EInteger.One);
                rat2 = ERational.Create(num, (EInteger)2);
                TestCommon.CompareTestLess(rat2, rat);
                TestCommon.CompareTestGreater(rat, rat2);
            }
            TestCommon.CompareTestLess(
                ERational.Create(EInteger.One, (EInteger)2),
                ERational.Create((EInteger)4, EInteger.One));
            for (var i = 0; i < 100; ++i)
            {
                EInteger num = RandomObjects.RandomEInteger(r);
                EInteger den = RandomObjects.RandomEInteger(r);
                if (den.IsZero)
                {
                    den = EInteger.One;
                }
                rat = ERational.Create(num, den);
                for (int j = 0; j < 10; ++j)
                {
                    EInteger num2 = num;
                    EInteger den2 = den;
                    EInteger mult = RandomObjects.RandomEInteger(r);
                    if (mult.IsZero || mult.Equals(EInteger.One))
                    {
                        mult = (EInteger)2;
                    }
                    num2 *= (EInteger)mult;
                    den2 *= (EInteger)mult;
                    rat2  = ERational.Create(num2, den2);
                    TestCommon.CompareTestEqual(rat, rat2);
                }
            }
        }
Beispiel #4
0
        public static ERational RandomERational(IRandomGenExtended rand)
        {
            EInteger bigintA = RandomEInteger(rand);
            EInteger bigintB = RandomEInteger(rand);

            if (bigintB.IsZero)
            {
                bigintB = EInteger.One;
            }
            return(ERational.Create(bigintA, bigintB));
        }
 /// <include file='../docs.xml'
 /// path='docs/doc[@name="M:PeterO.ExtendedRational.Create(PeterO.BigInteger,PeterO.BigInteger)"]/*'/>
 public static ExtendedRational Create(
     BigInteger numerator,
     BigInteger denominator)
 {
     if (numerator == null)
     {
         throw new ArgumentNullException(nameof(numerator));
     }
     if (denominator == null)
     {
         throw new ArgumentNullException(nameof(denominator));
     }
     return(new ExtendedRational(
                ERational.Create(
                    numerator.Ei,
                    denominator.Ei)));
 }
Beispiel #6
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 #7
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)));
            }
        }
 [Fact] public void FromERational() => Test(ERational.Create(EInteger.FromString("32324"), EInteger.FromString("243244")), ((Entity)"32324/243244").InnerSimplified);
Beispiel #9
0
        private static CBORNumber RationalToNumber(
            CBORObject o,
            int tagName)
        {
            if (o.Type != CBORType.Array)
            {
                return(null); // "Big fraction must be an array";
            }
            if (tagName == 270)
            {
                if (o.Count != 3)
                {
                    return(null); // "Extended big fraction requires exactly 3 items";
                }
                if (!IsUntaggedInteger(o[2]))
                {
                    return(null); // "Third item must be an integer";
                }
            }
            else
            {
                if (o.Count != 2)
                {
                    return(null); // "Big fraction requires exactly 2 items";
                }
            }
            if (!IsUntaggedIntegerOrBignum(o[0]))
            {
                return(null); // "Numerator is not an integer or bignum";
            }
            if (!IsUntaggedIntegerOrBignum(o[1]))
            {
                return(null); // "Denominator is not an integer or bignum");
            }
            EInteger numerator   = IntegerOrBignum(o[0]);
            EInteger denominator = IntegerOrBignum(o[1]);

            if (denominator.Sign <= 0)
            {
                return(null); // "Denominator may not be negative or zero");
            }
            ERational erat = ERational.Create(numerator, denominator);

            if (tagName == 270)
            {
                if (numerator.Sign < 0)
                {
                    return(null); // "Numerator may not be negative");
                }
                if (!o[2].CanValueFitInInt32())
                {
                    return(null); // "Invalid options";
                }
                int options = o[2].AsInt32Value();
                switch (options)
                {
                case 0:
                    break;

                case 1:
                    erat = erat.Negate();
                    break;

                case 2:
                    if (!numerator.IsZero || denominator.CompareTo(1) != 0)
                    {
                        return(null); // "invalid values");
                    }
                    erat = ERational.PositiveInfinity;
                    break;

                case 3:
                    if (!numerator.IsZero || denominator.CompareTo(1) != 0)
                    {
                        return(null); // "invalid values");
                    }
                    erat = ERational.NegativeInfinity;
                    break;

                case 4:
                case 5:
                case 6:
                case 7:
                    if (denominator.CompareTo(1) != 0)
                    {
                        return(null); // "invalid values");
                    }
                    erat = ERational.CreateNaN(
                        numerator,
                        options >= 6,
                        options == 5 || options == 7);
                    break;

                default: return(null); // "Invalid options");
                }
            }
            return(CBORNumber.FromObject(erat));
        }
Beispiel #10
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)));
            }
        }