예제 #1
0
	bignum root(const bignum &nth_root, const bignum &base_number, int decimal_places)
	{	
		//std::cout << "root calc" << std::endl;
		if (nth_root.getBase() != base_number.getBase())
			return root(nth_root, base_number.getConverted(nth_root.getBase()), decimal_places);

		//TODO: verify that the 2.5th root of -2 is irrational, 
		if (base_number.isNegative())
		{
			if (nth_root.getDecimalCount() > 0 || nth_root % 2 == 0)
				throw error_handler(__FILE__, __LINE__, "The program attempted to compute an irrational value");

			else return root(nth_root, base_number.absolute(), decimal_places) * -1;
		}	

		if (nth_root.isNegative())
		{
			bignum one(1);
			one.setBase(base_number.getBase());
			return root(nth_root.absolute(), one / base_number, decimal_places);
		}

		if (base_number == 0 || base_number == 1)
			return base_number;

		//cross-checks the root being tested to the precision threshold specified
		bignum precision_check(1);
		precision_check.setBase(nth_root.getBase());
		precision_check.rightShift(decimal_places);
		bignum range_low = base_number - precision_check;
		bignum range_high = base_number + precision_check;

		bignum root_test;
		root_test = base_number < 1 ? base_number * nth_root : base_number / nth_root;

		//TODO: refine increment function to scale depending on the size of the number being tested
		bignum increment(1);
		increment.setBase(nth_root.getBase());
		if (base_number < 1)
			increment.rightShift(1);

		bignum answer_check;
		answer_check.setBase(nth_root.getBase());

		//sets once function finds general region of the answer
		bool approximate = false;

		for (;;)
		{
			//adjusts number precision to check for nearest round roots
			//prevents function from returning 3.99999 instead of 4
			if (!approximate)
				root_test.roundToIndex(ONES_PLACE - increment.getDecimalCount());

			answer_check = exponent(root_test, nth_root);

			if (answer_check > range_low && answer_check < range_high)
				return root_test;

			if (answer_check > base_number)
			{
				if (approximate)
				{
					root_test -= increment;
					increment.rightShift(1);
					root_test += increment;
				}

				else root_test /= nth_root;
			}
				
			else if (answer_check < base_number)
			{
				if (!approximate)
					approximate = true;

				root_test += increment;
			}
		}
	}
예제 #2
0
 bignum operator-(const bignum& rop){ bignum num(*this); num += rop.minus(); return num; }
예제 #3
0
 void operator-=(const bignum& num){ operator+=(num.minus()); }
예제 #4
0
 bignum sub(const bignum& n){ bignum num(*this); num += n.minus(); return num; }