public BigNumber Neg() { BigNumber res = 0; BigNumber.Neg(this, res); return(res); }
static void M_log_basic_iteration(BigNumber nn, BigNumber rr, int places) { BigNumber tmp0, tmp1, tmp2, tmpX; if (places < 360) { BigNumber.M_log_solve_cubic(nn, rr, places); } else { tmp0 = new BigNumber(); tmp1 = new BigNumber(); tmp2 = new BigNumber(); tmpX = new BigNumber(); BigNumber.M_log_solve_cubic(nn, tmpX, 110); BigNumber.Neg(tmpX, tmp0); BigNumber.Exp(tmp0, tmp1, (places + 8)); BigNumber.Mul(tmp1, nn, tmp2); BigNumber.Sub(tmp2, BigNumber.One, tmp1); BigNumber.M_log_near_1(tmp1, tmp0, (places - 104)); BigNumber.Add(tmpX, tmp0, tmp1); BigNumber.Round(tmp1, rr, places); } }
static void Floor(BigNumber dst, BigNumber src) { BigNumber.Copy(src, dst); if (BigNumber.IsInteger(dst) > 0) { return; } if (dst.exponent <= 0) /* if |bb| < 1, result is -1 or 0 */ { if (dst.signum < 0) { BigNumber.Neg(BigNumber.One, dst); } else { BigNumber.SetZero(dst); } return; } if (dst.signum < 0) { BigNumber mtmp = new BigNumber(); BigNumber.Neg(dst, mtmp); mtmp.dataLength = mtmp.exponent; BigNumber.Normalize(mtmp); BigNumber.Add(mtmp, BigNumber.One, dst); dst.signum = -1; } else { dst.dataLength = dst.exponent; BigNumber.Normalize(dst); } }
static public void Sub(BigNumber src, BigNumber dst, BigNumber result) { int itmp, j, ChangeOrderFlag, icompare, aexp, bexp, borrow, adigits, bdigits; sbyte sign; BigNumber A = 0, B = 0; if (dst.signum == 0) { BigNumber.Copy(src, result); return; } if (src.signum == 0) { BigNumber.Copy(dst.Neg(), result); return; } if (src.signum == 1 && dst.signum == -1) { dst.signum = 1; Add(src, dst, result); dst.signum = -1; return; } if (src.signum == -1 && dst.signum == 1) { dst.signum = -1; Add(src, dst, result); dst.signum = 1; return; } BigNumber.Abs(A, src); BigNumber.Abs(B, dst); if ((icompare = Compare(A, B)) == 0) { SetZero(result); return; } if (icompare == 1) /* |a| > |b| (do A-B) */ { ChangeOrderFlag = 1; sign = src.signum; } else /* |b| > |a| (do B-A) */ { ChangeOrderFlag = 0; sign = (sbyte)-(src.signum); } aexp = A.exponent; bexp = B.exponent; if (aexp > bexp) { Scale(B, (aexp - bexp)); } if (aexp < bexp) { Scale(A, (bexp - aexp)); } adigits = A.dataLength; bdigits = B.dataLength; if (adigits > bdigits) { Pad(B, adigits); } if (adigits < bdigits) { Pad(A, bdigits); } if (ChangeOrderFlag == 1) // |a| > |b| (do A-B) { Copy(A, result); j = (result.dataLength + 1) >> 1; borrow = 0; while (true) { j--; itmp = ((int)result.mantissa[j] - ((int)B.mantissa[j] + borrow)); if (itmp >= 0) { result.mantissa[j] = (byte)itmp; borrow = 0; } else { result.mantissa[j] = (byte)(100 + itmp); borrow = 1; } if (j == 0) { break; } } } else // |b| > |a| (do B-A) instead { Copy(B, result); j = (result.dataLength + 1) >> 1; borrow = 0; while (true) { j--; itmp = (int)result.mantissa[j] - ((int)A.mantissa[j] + borrow); if (itmp >= 0) { result.mantissa[j] = (byte)itmp; borrow = 0; } else { result.mantissa[j] = (byte)(100 + itmp); borrow = 1; } if (j == 0) { break; } } } result.signum = sign; BigNumber.Normalize(result); }
static void Sqrt(BigNumber src, BigNumber dst, int places) { int ii, nexp, tolerance, dplaces; bool bflag; if (src.signum <= 0) { if (src.signum == -1) { throw new BigNumberException("'Sqrt',Invalid Argument"); } } BigNumber last_x = new BigNumber(); BigNumber guess = new BigNumber(); BigNumber tmpN = new BigNumber(); BigNumber tmp7 = new BigNumber(); BigNumber tmp8 = new BigNumber(); BigNumber tmp9 = new BigNumber(); BigNumber.Copy(src, tmpN); nexp = src.exponent / 2; tmpN.exponent -= 2 * nexp; BigNumber.SQrtGuess(tmpN, guess); tolerance = places + 4; dplaces = places + 16; bflag = false; BigNumber.Neg(BigNumber.Ten, last_x); ii = 0; while (true) { BigNumber.Mul(tmpN, guess, tmp9); BigNumber.Mul(tmp9, guess, tmp8); BigNumber.Round(tmp8, tmp7, dplaces); BigNumber.Sub(BigNumber.Three, tmp7, tmp9); BigNumber.Mul(tmp9, guess, tmp8); BigNumber.Mul(tmp8, BigNumber.BN_OneHalf, tmp9); if (bflag) { break; } BigNumber.Round(tmp9, guess, dplaces); if (ii != 0) { BigNumber.Sub(guess, last_x, tmp7); if (tmp7.signum == 0) { break; } /* * if we are within a factor of 4 on the error term, * we will be accurate enough after the *next* iteration * is complete. (note that the sign of the exponent on * the error term will be a negative number). */ if ((-4 * tmp7.exponent) > tolerance) { bflag = true; } } BigNumber.Copy(guess, last_x); ii++; } BigNumber.Mul(tmp9, tmpN, tmp8); BigNumber.Round(tmp8, dst, places); dst.exponent += nexp; }