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); } }
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); } } }
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))); } }
/// <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))); } }