public SimpleBigDecimal Add(SimpleBigDecimal b) { CheckScale(b); return new SimpleBigDecimal(bigInt.Add(b.bigInt), scale); }
public SimpleBigDecimal Subtract(SimpleBigDecimal b) { return Add(b.Negate()); }
private SimpleBigDecimal(SimpleBigDecimal limBigDec) { bigInt = limBigDec.bigInt; scale = limBigDec.scale; }
private void CheckScale(SimpleBigDecimal b) { if (scale != b.scale) throw new ArgumentException("Only SimpleBigDecimal of same scale allowed in arithmetic operations"); }
public int CompareTo(SimpleBigDecimal val) { CheckScale(val); return bigInt.CompareTo(val.bigInt); }
public BigInteger Round() { SimpleBigDecimal oneHalf = new SimpleBigDecimal(BigInteger.One, 1); return Add(oneHalf.AdjustScale(scale)).Floor(); }
public SimpleBigDecimal Multiply(SimpleBigDecimal b) { CheckScale(b); return new SimpleBigDecimal(bigInt.Multiply(b.bigInt), scale + scale); }
public SimpleBigDecimal Subtract(SimpleBigDecimal b) { return(Add(b.Negate())); }
public SimpleBigDecimal Add(SimpleBigDecimal b) { CheckScale(b); return(new SimpleBigDecimal(bigInt.Add(b.bigInt), scale)); }
public BigInteger Round() { SimpleBigDecimal oneHalf = new SimpleBigDecimal(BigInteger.One, 1); return(Add(oneHalf.AdjustScale(scale)).Floor()); }
public int CompareTo(SimpleBigDecimal val) { CheckScale(val); return(bigInt.CompareTo(val.bigInt)); }
public SimpleBigDecimal Multiply(SimpleBigDecimal b) { CheckScale(b); return(new SimpleBigDecimal(bigInt.Multiply(b.bigInt), scale + scale)); }
/** * Computes the norm of an element <code>λ</code> of * <code><b>R</b>[τ]</code>, where <code>λ = u + vτ</code> * and <code>u</code> and <code>u</code> are real numbers (elements of * <code><b>R</b></code>). * @param mu The parameter <code>μ</code> of the elliptic curve. * @param u The real part of the element <code>λ</code> of * <code><b>R</b>[τ]</code>. * @param v The <code>τ</code>-adic part of the element * <code>λ</code> of <code><b>R</b>[τ]</code>. * @return The norm of <code>λ</code>. */ public static SimpleBigDecimal Norm(sbyte mu, SimpleBigDecimal u, SimpleBigDecimal v) { SimpleBigDecimal norm; // s1 = u^2 SimpleBigDecimal s1 = u.Multiply(u); // s2 = u * v SimpleBigDecimal s2 = u.Multiply(v); // s3 = 2 * v^2 SimpleBigDecimal s3 = v.Multiply(v).ShiftLeft(1); if (mu == 1) { norm = s1.Add(s2).Add(s3); } else if (mu == -1) { norm = s1.Subtract(s2).Add(s3); } else { throw new ArgumentException("mu must be 1 or -1"); } return norm; }
public SimpleBigDecimal Divide(SimpleBigDecimal b) { CheckScale(b); BigInteger dividend = bigInt.ShiftLeft(scale); return new SimpleBigDecimal(dividend.Divide(b.bigInt), 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) { int 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"); BigInteger f0 = lambda0.Round(); BigInteger f1 = lambda1.Round(); SimpleBigDecimal eta0 = lambda0.Subtract(f0); SimpleBigDecimal eta1 = lambda1.Subtract(f1); // eta = 2*eta0 + mu*eta1 SimpleBigDecimal 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 SimpleBigDecimal threeEta1 = eta1.Add(eta1).Add(eta1); SimpleBigDecimal 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; } } BigInteger q0 = f0.Add(BigInteger.ValueOf(h0)); BigInteger q1 = f1.Add(BigInteger.ValueOf(h1)); return new ZTauElement(q0, q1); }
/** * 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) { int 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"); } BigInteger f0 = lambda0.Round(); BigInteger f1 = lambda1.Round(); SimpleBigDecimal eta0 = lambda0.Subtract(f0); SimpleBigDecimal eta1 = lambda1.Subtract(f1); // eta = 2*eta0 + mu*eta1 SimpleBigDecimal 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 SimpleBigDecimal threeEta1 = eta1.Add(eta1).Add(eta1); SimpleBigDecimal 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; } } BigInteger q0 = f0.Add(BigInteger.ValueOf(h0)); BigInteger q1 = f1.Add(BigInteger.ValueOf(h1)); return(new ZTauElement(q0, q1)); }