protected override BigNum Multiply(BigNum multiplicand) { return(BigFloat.Multiply(this, (BigFloat)multiplicand)); }
public static BigFloat Divide(BigFloat dividend, BigFloat divisor, out Boolean isExact) { if (divisor.IsZero) { throw new DivideByZeroException(); } isExact = true; if (dividend.IsZero) { return((BigFloat)dividend.Clone()); } /////////////////////////////// BigFloat quotient = new BigFloat(); quotient._sign = dividend.Sign == divisor.Sign; dividend = (BigFloat)dividend.Absolute(); divisor = (BigFloat)divisor.Absolute(); BigFloat aPortion; BigFloat bDigit = null; ////////////////////////////// while (divisor[0] == 0) // remove least-significant zeros and up the exponent to compensate { divisor._exp++; divisor._data.RemoveAt(0); } quotient._exp = dividend.Length + dividend._exp - divisor.Length - divisor._exp + 1; dividend._exp = 0; divisor._exp = 0; aPortion = new BigFloat(); Int32 bump = 0, c = -1; Boolean hump = false; isExact = false; while (quotient.Length < _divisionDigits) // abandon hope all ye who enter here { aPortion = dividend.Msd(divisor.Length + (hump ? 1 : 0)); if (aPortion < divisor) { int i = 1; while (aPortion < divisor) { aPortion = dividend.Msd(divisor.Length + i + (hump ? 1 : 0)); quotient._exp--; quotient._data.Add(0); i++; } hump = true; } bDigit = 0; //tt = 0; c = 0; while (bDigit < aPortion) { bDigit = (BigFloat)bDigit.Add(divisor); //tt += b; c++; } if (bDigit != aPortion) { c--; bDigit = new BigFloat(c); bDigit = (BigFloat)bDigit.Multiply(divisor); //tt *= b; isExact = false; } else { isExact = true; } quotient._data.Add((sbyte)c); quotient._exp--; aPortion.Normalise(); dividend.Normalise(); bump = aPortion.Length - bDigit.Length; if (aPortion.Length > dividend.Length) { dividend = aPortion; } bDigit = bDigit.Msd(dividend.Length - bump); aPortion = BigFloat.Add(dividend, (BigFloat)bDigit.Negate(), false); dividend = (BigFloat)aPortion.Clone(); if (aPortion.IsZero) { break; // no more work necessary } if (hump) { if (dividend[dividend.Length - 1] == 0) { dividend._data.RemoveAt(dividend.Length - 1); } } if (dividend[dividend.Length - 1] == 0) { dividend._data.RemoveAt(dividend.Length - 1); while (dividend[dividend.Length - 1] == 0) { quotient._exp--; quotient._data.Add(0); dividend._data.RemoveAt(dividend.Length - 1); if (dividend.Length == 0) { break; } } if (dividend.Length == 0) { break; } hump = false; } else { hump = true; } if (quotient.Length == 82) { c = 0; } } quotient._data.Reverse(); quotient.Normalise(); return(quotient); }
public static BigFloat Divide(BigFloat dividend, BigFloat divisor, out Boolean isExact) { if(divisor.IsZero) throw new DivideByZeroException(); isExact = true; if(dividend.IsZero) return (BigFloat)dividend.Clone(); /////////////////////////////// BigFloat quotient = new BigFloat(); quotient._sign = dividend.Sign == divisor.Sign; dividend = (BigFloat)dividend.Absolute(); divisor = (BigFloat)divisor.Absolute(); BigFloat aPortion; BigFloat bDigit = null; ////////////////////////////// while( divisor[0] == 0 ) { // remove least-significant zeros and up the exponent to compensate divisor._exp++; divisor._data.RemoveAt(0); } quotient._exp = dividend.Length + dividend._exp - divisor.Length - divisor._exp + 1; dividend._exp = 0; divisor._exp = 0; aPortion = new BigFloat(); Int32 bump = 0, c = -1; Boolean hump = false; isExact = false; while( quotient.Length < _divisionDigits ) { // abandon hope all ye who enter here aPortion = dividend.Msd( divisor.Length + ( hump ? 1 : 0 ) ); if( aPortion < divisor ) { int i = 1; while( aPortion < divisor ) { aPortion = dividend.Msd( divisor.Length + i + ( hump ? 1 : 0 ) ); quotient._exp--; quotient._data.Add( 0 ); i++; } hump = true; } bDigit = 0; //tt = 0; c = 0; while( bDigit < aPortion ) { bDigit = (BigFloat)bDigit.Add(divisor); //tt += b; c++; } if( bDigit != aPortion ) { c--; bDigit = new BigFloat( c ); bDigit = (BigFloat)bDigit.Multiply(divisor); //tt *= b; isExact = false; } else { isExact = true; } quotient._data.Add( (sbyte)c ); quotient._exp--; aPortion.Normalise(); dividend.Normalise(); bump = aPortion.Length - bDigit.Length; if( aPortion.Length > dividend.Length ) dividend = aPortion; bDigit = bDigit.Msd( dividend.Length - bump ); aPortion = BigFloat.Add(dividend, (BigFloat)bDigit.Negate(), false ); dividend = (BigFloat)aPortion.Clone(); if( aPortion.IsZero ) break; // no more work necessary if( hump ) { if( dividend[dividend.Length - 1] == 0 ) { dividend._data.RemoveAt( dividend.Length - 1 ); } } if( dividend[dividend.Length - 1] == 0 ) { dividend._data.RemoveAt( dividend.Length - 1 ); while( dividend[dividend.Length - 1] == 0 ) { quotient._exp--; quotient._data.Add( 0 ); dividend._data.RemoveAt( dividend.Length - 1 ); if( dividend.Length == 0 ) break; } if( dividend.Length == 0 ) break; hump = false; } else { hump = true; } if( quotient.Length == 82 ) { c = 0; } } quotient._data.Reverse(); quotient.Normalise(); return quotient; }