public static Fp Mul(Fp a, Fp b) { double[] r = new double[POS_COUNT * 2]; double carry = 0; int ri; for (int ai = POS_COUNT - 1; ai >= 0; ai--) { ri = ai + POS_COUNT; for (int bi = POS_COUNT - 1; bi >= 0; bi--) { //string lh = a.GetDigitBin(ai); //string rh = b.GetDigitBin(bi); double p = r[ri] + carry + a._digs[ai] * b._digs[bi]; carry = BreakUp(p, BASE, out double remain); r[ri] = remain; ri--; } } //r[0] = carry; if (carry != 0) { throw new OverflowException("Multiplication has caused an overflow."); } //DMathUtil.ReportDigitsBin(a.GetDouble(), r); int cl = POS_COUNT; //int cl = POS_COUNT * 2 - 1; //cl = 2; double[] rr = new double[cl]; for (int i = 0; i < cl; i++) { rr[i] = r[i + 1]; } Fp tResult = new Fp(rr); if (r[POS_COUNT + 1] > HALF_BASE) { //rr[POS_COUNT - 1] += Math.Pow(2, (POS_COUNT - 1) * -STEP); //Fp result = Add(tResult, new Fp(Math.Pow(2, (POS_COUNT - 1) * -STEP))); //return result; return(tResult); } else { return(tResult); } }
public static Fp Add(Fp a, int b) { double carry = BreakUp(a._digs[0] + b, BASE, out double remain); if (carry != 0) { throw new OverflowException("Addition (with integer) has resulted in an overflow."); } Fp result = new Fp(a); result._digs[0] += b; return(result); }
// LSB * each of b //a2 * b2 -> r5; //a2 * b1 -> r4; //a2 * b0 -> r3; //a1 * b2 -> r4; //a1 * b1 -> r5; //a1 * b0 -> r2; // HSB * each of b //a0 * b2 -> r3; //a0 * b1 -> r2; //a0 * b0 -> r1; // multiply(a[1..p], b[1..q], base) // Operands containing rightmost digits at index 1 // product = [1..p+q] // Allocate space for result // for b_i = 1 to q // for all digits in b //carry = 0 // for a_i = 1 to p // for all digits in a // product[a_i + b_i - 1] += carry + a[a_i] * b[b_i] // carry = product[a_i + b_i - 1] / base // product[a_i + b_i - 1] = product[a_i + b_i - 1] mod base //product[b_i + p] = carry // last digit comes from final carry // return product public static Fp Add(Fp a, Fp b) { double[] r = new double[POS_COUNT]; double carry = 0; for (int i = POS_COUNT - 1; i >= 0; i--) { double s = carry + a._digs[i] + b._digs[i]; carry = BreakUp(s, BASE, out double remain); r[i] = remain; } if (carry != 0) { throw new OverflowException("Addition has resulted in an overflow."); } return(new Fp(r)); }
public Fp(Fp x) : this(x._digs) { }