//•••••••••••••••••••••••••••••••••••••••••••••••••••••••• /// <summary> /// Root of variable degree /// </summary> /// <param name="_NDegree">root degree</param> /// <param name="_N">value, root of which to be taken</param> /// <returns>result of variable degree</returns> public static CNumber Root(CNumber _NDegree, CNumber _N) { CCalculator.ASSERT((_NDegree.dValue != 0.0d) , "(y)_#(x): `y` - Root degree can't be NULL.", "CMath.Root binary"); CCalculator.ASSERT((_N.dValue >= 0.0d) || (_NDegree.dValue % 2 != 0) , "(y)_#(x): `x` - Must be positive and/or `y` is even." , "CMath.Root binary"); m_res = new CNumber("0", _N); m_res.Value = _N.Value; double X = Math.Abs(_N.dValue); try { m_res.Value = Math.Pow(2, Math.Log(X, 2) / _NDegree.dValue); // changing sign of result if root argument was negative and // root degree was uneven if (_N.dValue < 0) { m_res.Value = -m_res.dValue; } } catch (OverflowException) { CCalculator.ASSERT(false, "", ""); } return(m_res); }
//•••••••••••••••••••••••••••••••••••••••••••••••••••••••• public static CNumber Xor(CNumber _N1, CNumber _N2) { CCalculator.ASSERT(_N1.IsInteger && _N2.IsInteger , "\"XOR\" operation need integer.", "CMath.Xor"); m_res = new CNumber("0", _N1); m_res.Value = (long)_N1.Value ^ (long)_N2.Value; return(m_res); }
//•••••••••••••••••••••••••••••••••••••••••••••••••••••••• public static CNumber Not(CNumber _num) { CCalculator.ASSERT(_num.IsInteger , "\"NOT\" operation need integer.", "CMath.Not"); m_res = new CNumber("0", _num); m_res.Value = ~((long)_num.Value); return(m_res); }
//•••••••••••••••••••••••••••••••••••••••••••••••••••••••• /// <summary> /// Square root (degree of 2)</summary> /// <param name="_N">value, root of which to be evaluated</param> /// <returns>result of root of degree 2</returns> public static CNumber Root(CNumber _N) { CCalculator.ASSERT(_N.dValue > 0.0d , "#(x): x - Must be positive.", "CMath.Root unary"); m_res = new CNumber("0", _N); m_res.Value = Math.Sqrt(_N.dValue); return(m_res); }
//•••••••••••••••••••••••••••••••••••••••••••••••••••••••• /// <summary> /// Regular devision /// </summary> /// <param name="_NDividend"></param> /// <param name="_NDivisor"></param> /// <returns></returns> public static CNumber Div(CNumber _NDividend, CNumber _NDivisor) { m_res = new CNumber("0", _NDividend); CCalculator.ASSERT(_NDivisor.dValue != 0.0d , "Divide by zero.", "CMath.Div"); m_res.Value = _NDividend.dValue / _NDivisor.dValue; return(m_res); }
//•••••••••••••••••••••••••••••••••••••••••••••••••••••••• /// <summary>Binary Logarithm of variable base</summary> /// <param name="_base">base</param> /// <param name="_num">argument</param> /// <returns>Returns the _sBase logarithm of a specified number</returns> public static CNumber Log(CNumber _base, CNumber _num) { CCalculator.ASSERT(_base.dValue >= 0 , "(y)Log(x): y - POSITIVE expected." , "CMath.Log"); m_res = new CNumber("0", _num); m_res.Value = Math.Log(_num.dValue, _base.dValue); return(m_res); }
/// <summary>Binary. Find the grat common devisor of two /// integer numbers</summary> static public CNumber GCD(CNumber _n1, CNumber _n2) { CCalculator.ASSERT(_n1.IsInteger && _n2.IsInteger , "(x)Gcd(y): x, y - Integers expected.", "CMath.GCD"); m_res = new CNumber("0", _n1); m_res.Value = _gcd(_n1.lValue, _n2.lValue); return(m_res); }
//•••••••••••••••••••••••••••••••••••••••••••••••••••••••• public static CNumber ShiftRight(CNumber _N, CNumber _BitNum) { CCalculator.ASSERT(_N.IsInteger && _BitNum.IsInteger , "\">>\" operation need integer.", "CMath.ShiftRight"); m_res = new CNumber("0", _N); try { int bitNum = Convert.ToInt32((long)_BitNum.Value); m_res.Value = (long)_N.Value >> bitNum; } catch (OverflowException) { CCalculator.ASSERT(false, "\"x >> Y\" - Y overflow.", "CMath.ShiftRight"); } return(m_res); }
//•••••••••••••••••••••••••••••••••••••••••••••••••••••••• public static CNumber Factorial(CNumber _num) { CCalculator.ASSERT(_num.IsInteger , "\"!x\" operation need integer.", "CMath.Factorial"); m_res = new CNumber("0", _num); if ((long)_num.Value == 0) { m_res.Value = 1L; return(m_res); } try { if (_num.dValue <= 20) { long num = (long)_num.Value; long fact = num; while (num > 1) { fact *= --num; } m_res.Value = fact; } else { double num = _num.dValue; double fact = num; while (num > 1) { fact *= --num; } m_res.Value = fact; } } catch (OverflowException) { CCalculator.ASSERT(false , "Result is out of range.", "CMath.Factorial"); } return(m_res); }
/// <summary> /// Convert digital substance of the CNumber value to its string equivalent, /// based on culture format provider, Count-System (CS) and precision. /// </summary> /// <returns></returns> public override string ToString() { if (m_prec != T_PREC.DEFAULT && m_prec != T_PREC.ROUNDTRIP) { switch (m_prec) { case T_PREC._0: m_fp.NumberDecimalDigits = 0; break; case T_PREC._1: m_fp.NumberDecimalDigits = 1; break; case T_PREC._2: m_fp.NumberDecimalDigits = 2; break; case T_PREC._3: m_fp.NumberDecimalDigits = 3; break; case T_PREC._5: m_fp.NumberDecimalDigits = 5; break; case T_PREC._8: m_fp.NumberDecimalDigits = 8; break; case T_PREC._13: m_fp.NumberDecimalDigits = 13; break; } } string str = ""; // if it decimal there is the sence to make precision fitting if (m_cs == T_CS.DEC) { // convert to default representation if (m_prec == T_PREC.DEFAULT) { str = (((m_value is double)? (double)m_value :(long)m_value)).ToString(); } // this precision gives recalculable result else if (m_prec == T_PREC.ROUNDTRIP) { str = (((m_value is double)? (double)m_value :(long)m_value)).ToString("R"); } // other precision else { str = (((m_value is double)? (double)m_value :(long)m_value)).ToString("N", m_fp); } } // in case of other Count System the result will be `long` converted, // in case of double-type-banking that operation may lead to Overflow. else { try { switch (m_cs) { case T_CS.HEX: str = Convert.ToString(Convert.ToInt64(m_value), 16); break; case T_CS.OCT: str = Convert.ToString(Convert.ToInt64(m_value), 8); break; case T_CS.BIN: str = Convert.ToString(Convert.ToInt64(m_value), 2); break; } } catch (System.OverflowException) { CCalculator.ASSERT(false , "Result exceed 64bits in \"" + m_cs.ToString() + "\" count system.", "CNumber.ToString"); } if (m_cs == T_CS.HEX) { str = "0x" + GroupBy(8, str); } else if (m_cs == T_CS.OCT) { str = GroupBy(3, str) + ".oct"; } else if (m_cs == T_CS.BIN) { str = GroupBy(4, str) + ".bin"; } } return(str); }