SimpleBigDecimal(SimpleBigDecimal limBigDec) { this.bigInt = limBigDec.bigInt; this.Scale = limBigDec.Scale; }
/** * Rounds an element * <code>λ</code> * of * <code><b>R</b>[τ]</code> * to an element of * <code><b>Z</b>[τ]</code> * , such that their difference * has minimal norm. * <code>λ</code> * is given as * <code>λ = λ<sub>0</sub> + λ<sub>1</sub>τ</code> * . * @param lambda0 The component * <code>λ<sub>0</sub></code> * . * @param lambda1 The component * <code>λ<sub>1</sub></code> * . * @param mu The parameter * <code>μ</code> * of the elliptic curve. Must * equal 1 or -1. * @return The rounded element of * <code><b>Z</b>[τ]</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"); }