SimpleBigDecimal(SimpleBigDecimal limBigDec)
 {
     this.bigInt = limBigDec.bigInt;
     this.Scale = limBigDec.Scale;
 }
Пример #2
0
        /**
         * Rounds an element
         * <code>&#955;</code>
         * of
         * <code><b>R</b>[&#964;]</code>
         * to an element of
         * <code><b>Z</b>[&#964;]</code>
         * , such that their difference
         * has minimal norm.
         * <code>&#955;</code>
         * is given as
         * <code>&#955; = &#955;<sub>0</sub> + &#955;<sub>1</sub>&#964;</code>
         * .
         * @param lambda0 The component
         * <code>&#955;<sub>0</sub></code>
         * .
         * @param lambda1 The component
         * <code>&#955;<sub>1</sub></code>
         * .
         * @param mu The parameter
         * <code>&#956;</code>
         * of the elliptic curve. Must
         * equal 1 or -1.
         * @return The rounded element of
         * <code><b>Z</b>[&#964;]</code>
         * .
         * @throws ArgumentException if
         * <code>lambda0</code>
         * and
         * <code>lambda1</code>
         * do not have same scale.
         */
        public static ZTauElement Round(SimpleBigDecimal lambda0,
                                        SimpleBigDecimal lambda1, sbyte mu)
        {
            var scale = lambda0.Scale;

            if (lambda1.Scale != scale)
            {
                throw new ArgumentException("lambda0 and lambda1 do not have same scale");
            }

            if (!(mu == 1 || mu == -1))
            {
                throw new ArgumentException("mu must be 1 or -1");
            }

            var f0 = lambda0.Round();
            var f1 = lambda1.Round();

            var eta0 = lambda0.Subtract(f0);
            var eta1 = lambda1.Subtract(f1);

            // eta = 2*eta0 + mu*eta1
            var eta = eta0.Add(eta0);

            if (mu == 1)
            {
                eta = eta.Add(eta1);
            }
            else
            {
                // mu == -1
                eta = eta.Subtract(eta1);
            }

            // check1 = eta0 - 3*mu*eta1
            // check2 = eta0 + 4*mu*eta1
            var threeEta1 = eta1.Add(eta1).Add(eta1);
            var fourEta1  = threeEta1.Add(eta1);
            SimpleBigDecimal check1;
            SimpleBigDecimal check2;

            if (mu == 1)
            {
                check1 = eta0.Subtract(threeEta1);
                check2 = eta0.Add(fourEta1);
            }
            else
            {
                // mu == -1
                check1 = eta0.Add(threeEta1);
                check2 = eta0.Subtract(fourEta1);
            }

            sbyte h0 = 0;
            sbyte h1 = 0;

            // if eta >= 1
            if (eta.CompareTo(BigInteger.One) >= 0)
            {
                if (check1.CompareTo(MinusOne) < 0)
                {
                    h1 = mu;
                }
                else
                {
                    h0 = 1;
                }
            }
            else
            {
                // eta < 1
                if (check2.CompareTo(BigInteger.Two) >= 0)
                {
                    h1 = mu;
                }
            }

            // if eta < -1
            if (eta.CompareTo(MinusOne) < 0)
            {
                if (check1.CompareTo(BigInteger.One) >= 0)
                {
                    h1 = (sbyte)-mu;
                }
                else
                {
                    h0 = -1;
                }
            }
            else
            {
                // eta >= -1
                if (check2.CompareTo(MinusTwo) < 0)
                {
                    h1 = (sbyte)-mu;
                }
            }

            var q0 = f0.Add(BigInteger.ValueOf(h0));
            var q1 = f1.Add(BigInteger.ValueOf(h1));

            return(new ZTauElement(q0, q1));
        }
 public int CompareTo(SimpleBigDecimal val)
 {
     CheckScale(val);
     return this.bigInt.CompareTo(val.bigInt);
 }
 public BigInteger Round()
 {
     var oneHalf = new SimpleBigDecimal(BigInteger.One, 1);
     return Add(oneHalf.AdjustScale(this.Scale)).Floor();
 }
 public SimpleBigDecimal Divide(SimpleBigDecimal b)
 {
     CheckScale(b);
     var dividend = this.bigInt.ShiftLeft(this.Scale);
     return new SimpleBigDecimal(dividend.Divide(b.bigInt), this.Scale);
 }
 public SimpleBigDecimal Multiply(SimpleBigDecimal b)
 {
     CheckScale(b);
     return new SimpleBigDecimal(this.bigInt.Multiply(b.bigInt), this.Scale + this.Scale);
 }
 public SimpleBigDecimal Subtract(SimpleBigDecimal b)
 {
     return Add(b.Negate());
 }
 public SimpleBigDecimal Add(SimpleBigDecimal b)
 {
     CheckScale(b);
     return new SimpleBigDecimal(this.bigInt.Add(b.bigInt), this.Scale);
 }
 void CheckScale(SimpleBigDecimal b)
 {
     if (this.Scale != b.Scale)
         throw new ArgumentException("Only SimpleBigDecimal of same scale allowed in arithmetic operations");
 }