
/**
 * @name CeL integer function
 * @fileoverview
 * 本檔案包含了整數 (integer) 暨小數的 functions，相當/類似於 BigInteger, bigint, Large number。<br />
 * 在純 javascript 的環境下，藉由原生計算功能，盡可能提供高效的大數計算。<br />
 * integer 大數基本上即為 Integer.BASE 進位制之數字系統(Positional notation or place-value notation)。
 *
 * @example
 * <code>
 * CeL.run('data.math.integer');
 * var integer = new CeL.integer('654561264556287547824234523');
 * CeL.log(integer.add('096527893048039647894'));
 * </code>
 *
 * @since 2013/9/8 13:42:58
 * @see
 * https://zh.wikipedia.org/wiki/%E9%80%B2%E4%BD%8D%E5%88%B6
 */


/*
TODO:
在 ECMAScript 6 之後，或可以繼承重寫。
為了減輕負擔，有些屬性可以不放在 Integer.prototype。

http://reference.wolfram.com/mathematica/tutorial/SomeNotesOnInternalImplementation.html
http://gmplib.org/
http://www.craig-wood.com/nick/articles/pi-chudnovsky/

Arbitrary-precision arithmetic / 高精度計算
https://en.wikipedia.org/wiki/Arbitrary-precision_arithmetic

http://msdn.microsoft.com/zh-tw/library/system.numerics.biginteger.aspx
http://docs.oracle.com/javase/7/docs/api/java/math/BigInteger.html


https://github.com/silentmatt/javascript-biginteger
https://github.com/peterolson/BigInteger.js
https://github.com/peterolson/BigRational.js
https://github.com/cwacek/bigint-node/blob/master/lib/bigint.js

http://www.leemon.com/crypto/BigInt.html
http://www-cs-students.stanford.edu/~tjw/jsbn/
http://java.sun.com/javase/6/docs/api/java/math/BigInteger.html


規格書:

integer = new Integer(number,        do not set fraction = false, base = default base);
integer = new Integer(number String, base of String,              base = default base);
integer = new Integer(Integer,       (ignored),                   base = default base);

// digit Array
integer[{integer}digit index] = the digit of base ^ (index + exponent)
integer[KEY_NEGATIVE]		= {Undefined|Boolean}this integer is negative
integer[KEY_BASE]			= {natural number}base of this integer
integer[KEY_EXPONENT]		= {integer}exponent of this integer
integer[KEY_CACHE]			= {Undefined|Array}cache String of value
integer[KEY_CACHE][base]	= {String}value in base
integer[KEY_TYPE]			= {Undefined|Number}NaN / Infinity
integer[KEY_FACTORS]		= {Undefined|Array}factors / 因數
integer[KEY_FACTORS].sort(function(a,b){var na=Array.isArray(a),nb=Array.isArray(b);return na^nb?na^0:na&&nb?a.length-b.length||a[a.length-1]-b[b.length-1]:a-b;});


*/


if (typeof CeL === 'function')
	CeL.run(
	{
		name: 'data.math.integer',
		require: 'data.code.compatibility.|data.native.|data.math.GCD',
		no_extend: 'random,compare',
		code: function (library_namespace) {
			'use strict';

			//	requiring
			var GCD = this.r('GCD');

			// ---------------------------------------------------------------------//
			// basic constants. 定義基本常數。

			var

			// assert: isNaN(KEY_*)
			// {safe integer} MIN_BASE <= instance[KEY_BASE] <= MAX_BASE
			// instance[KEY_BASE] 基數/底數初始設定完後，除非歸零，否則不可再改變!
			KEY_BASE = 'base',
			// sign. true: *this* is negative, false/undefined: positive.
			KEY_NEGATIVE = 'negative',
			//{integer|Undefined}[exponent]	輸入數值標記之科學記數法指數 in instance[KEY_BASE]。default 0.
			KEY_EXPONENT = 'exponent',
			//僅為大數整數分解（因數分解, integer factorization）存在。
			// this[KEY_FACTORS] = [ {safe integer}scalar純量, Integer, ..]
			KEY_FACTORS = 'factors',
			// instance[KEY_CACHE][base] = string in base;
			KEY_CACHE = 'cache',
			//instance[KEY_TYPE] = NaN / Infinity; unset: instance is normal number.
			// 指示/存儲特殊值。 ** instance[\d] 本身僅存儲純數字。
			KEY_TYPE = 'type',

			// 本 library 所允許之最大可安全計算整數。MAX_SAFE_INTEGER <= Number.MAX_SAFE_INTEGER。
			MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER,

			// see for_each_digit()
			//之後再作初始化。
			// assert: 1 < MIN_BASE <= MAX_BASE
			MIN_BASE = 0,
			// assert: MAX_BASE * MAX_BASE < MAX_SAFE_INTEGER + 2
			// see change_base_to(), for_each_digit()
			//	為方便乘法處理，因此取自乘不致 overflow ( > MAX_SAFE_INTEGER) 之值，預防 overflow 用。
			MAX_BASE = Math.floor(Math.sqrt(MAX_SAFE_INTEGER)),

			// 可辨認之數字字串。
			//	[ full , sign, integer part 整數部分, fractional part 小數部分, exponent 指數, percent ]
			PATTERN_NUMBER = /([+\-]?)([\d]*)(?:\.([\d]+))?(?:[eE]([+\-]?\d+))?\s*([%‰‱])?/,
			// hex 用。
			//	[ full , sign, integer part 整數部分, fractional part 小數部分, exponent 指數, percent ]
			PATTERN_NUMBER_HEX = /([+\-]?)([\da-z]*)(?:\.([\da-z]+))?(?:[eE]([+\-]?\d+))?\s*([%‰‱])?/,
			// https://en.wikipedia.org/wiki/Parts-per_notation
			exponent_parts_per = {
				// percentage (%), 百分比, ％（全形百分號）
				'%' : -2,
				// permille (‰), 千分率
				'‰' : -3,
				// permyriad (‱) (Basis point), 萬分率
				'‱' : -4
				// ppm (parts-per-million, 10–6), ppb (parts-per-billion, 10–9), ppt (parts-per-trillion, 10–12) and ppq (parts-per-quadrillion, 10-15).
			},

			//當展現十進位數字時，若非無窮小數，則最多可展現之位數。
			MAX_TRUNCATED = get_precision(1 / 3) - 1,

			DECIMAL_BASE_LENGTH = Math.log10(MAX_SAFE_INTEGER) >> 1,
			DECIMAL_BASE = (1 + '0'.repeat(DECIMAL_BASE_LENGTH)) | 0,
			//	default base.
			DEFAULT_BASE = DECIMAL_BASE,

			MULTIPLICATION_BOUNDARY = multiplication_boundary(DEFAULT_BASE),

			/**
			 * parseInt( , radix) 可處理之最大 radix，<br />
			 * 與 Number.prototype.toString ( [ radix ] )<br />
			 * 可用之最大基數 (radix, base)。<br />
			 * 10 Arabic numerals + 26 Latin alphabet.<br />
			 * 之後再作初始化。
			 *
			 * @inner
			 * @see
			 * <a href="https://en.wikipedia.org/wiki/Hexadecimal" accessdate="2013/9/8 17:26">Hexadecimal</a>
			 */
			MAX_RADIX = 0,
			// 之後再作初始化。
			MIN_RADIX = 0,
			// 應與 parseInt() 一致。
			DEFAULT_RADIX = parseInt('10'),
			HEX_RADIX = parseInt('0x10'),
			PATTERN_HEX = new RegExp('^0x([0-9a-f]{' + Number.MAX_SAFE_INTEGER.toString(HEX_RADIX).length + ',})$', 'i'),

			// 數字過大，parseInt() 無法獲得精密數值時使用 DEFAULT_DIGITS。不分大小寫。應與 parseInt() 一致。
			// assert: DEFAULT_DIGITS.length === MAX_RADIX
			// assert: DEFAULT_DIGITS.toLowerCase() === DEFAULT_DIGITS
			DEFAULT_DIGITS = '',
			DEFAULT_DIGITS_CACHE,

			// copy from data.math
			MULTIPLICATIVE_IDENTITY = library_namespace.MULTIPLICATIVE_IDENTITY,
			// copy from data.math
			ZERO_EXPONENT = library_namespace.ZERO_EXPONENT,
			// copy from data.math
			ABSORBING_ELEMENT = library_namespace.ABSORBING_ELEMENT,

			trim_0,

			// radix point / radix character / decimal mark 小數點
			radix_point = '.',

			// Array 或 Uint32Array。
			array_type = Array,
			// array_clone(from, to[, assignment]): 在不改變 to 之 reference 下，將 to 之陣列內容改為與 from 相同。
			array_clone,
			//reset digits of (this)
			array_reset,
			//
			shift_digits;

			// ---------------------------------------------------------------------//

			/**
			 * front end of operation(運算)
			 * @param {String}operator	operator
			 * @param number	the second integer
			 * @return	計算後的結果
			 * @see
			 * https://en.wikipedia.org/wiki/Operation_(mathematics)
			 * <a href="http://www.javaworld.com.tw/jute/post/view?bid=35&amp;id=30169&amp;tpg=1&amp;ppg=1&amp;sty=1&amp;age=0#30169" accessdate="2010/4/16 20:47">JavaWorld@TW Java論壇 - post.view</a>
			 * @_name	_module_.prototype.op
			 */
			function operate(OP_SET, target, operator, operand, flag) {
				if (operator.slice(-1) === '=') {
					if (operator === '===')
						return target === operand;
					if (operator !== '=' && operator !== '==')
						operator = operator.slice(0, -1);
					// 避免 target +-×÷ target
					if (target === operand)
						target = target.clone();
				} else
					target = target.clone();

				if (operator in OP_SET)
					OP_SET[operator].call(target, operand, flag);
				else
					library_namespace.error('operate: Invalid operator [' + operator + ']!');

				return target;
			}

			function set_operate(OP_SET) {
				return function (operator, operand, flag) {
					return operate(OP_SET, this, operator, operand, flag);
				};
			}


			// ---------------------------------------------------------------------//
			// 初始調整並規範基本常數。

			/**
			 * 工具函數：轉換 ['a','b','c'] → {a:0,b:1,c:2}。
			 *
			 * @param	{Array}[base]	輸入數值採用之進位制基底/數字 digit 字集。
			 *
			 * @return	回傳 cache 物件。
			 *
			 * @inner
			 */
			function digit_cache(base) {
				var digits = Object.create(null);
				base.forEach(function (digit, index) {
					if (digit.length !== 1)
						library_namespace.error('digit_cache: Invalid digit: [' + digit + '].');
					else if (digit in digits)
						library_namespace.error('Digit already exists: [' + digit + '] = ' + digits[digit]);
					else
						digits[digit] = index;
				});
				return digits;
			}

			// 工具函數
			//truncation: truncate array to length
			function Array_reset(array, to_length) {
				// 或可參考:
				// http://stackoverflow.com/questions/1232040/how-to-empty-an-array-in-javascript
				to_length = array.length - (to_length | 0);
				while (0 < to_length--)
					array.pop();
				return array;
			}

			function General_reset(array, to_length) {
				var i = array.length;
				to_length |= 0;
				while (to_length < i--)
					array[i] = 0;
				return [];
			}

			function Array_clone(from, to) {
				if (from !== to) {
					Array_reset(to);
					array_type.prototype.push.apply(to, from);
				}
			}

			function General_clone(from, to) {
				if (from !== to) {
					var index = to.length, l = from.length;
					if (index < l) {
						library_namespace.warn('General_clone: Target array has a shorter length!');
						//index = l;
					} else
						while (l < index)
							//高位補 0。
							to[--index] = 0;
					// assert: index <= from.length, should be (from.length).
					while (0 < index--)
						to[index] = from[index];
				}
			}

			// 清理高數位的 0。
			function Array_trim_0(integer, preserve) {
				var index = integer.length;
				// 1 < index: 直接保留最後一個，省得麻煩。
				if (preserve === undefined)
					preserve = 1;
				// assert: integer[index] is integer
				while (preserve < index-- && integer[index] === 0);
				integer.length = index + 1;
				return integer;
			}

			//exponent > 0 時，會去掉尾數 exponent 個 digits。
			//exponent < 0 時，會補上尾數 exponent 個 digits。
			function Array_shift_digits(integer, exponent, no_set_exponent) {
				if (exponent |= 0) {
					if (!no_set_exponent)
						integer[KEY_EXPONENT] += exponent;
					if (0 < exponent)
						integer.splice(0, exponent);
					else {
						//當 exponent 量過大(e.g., 在 .precise_divide() 中，循環節 period = 71687)，Chrome 32 用
						//<code>Array.prototype.unshift.apply(integer, new Array(-exponent));</code>
						//會出現 RangeError: Maximum call stack size exceeded
						var a = integer.slice();
						integer.length = -exponent;
						integer.fill(0);
						Array.prototype.push.apply(integer, a);
					}
				}
			}

			function General_shift_digits(integer, exponent) {
				if (exponent |= 0) {
					if (!no_set_exponent)
						integer[KEY_EXPONENT] += exponent;
					if (0 < exponent)
						for (var i = 0, l = integer.length; i < l; i++)
							integer[i] = i + exponent < l ? integer[i + exponent] : 0;
					else
						for (var i = integer.length - 1; 0 <= i; i--)
							integer[i] = i + exponent < 0 ? 0 : integer[i + exponent];
				}
			}


			//找出最小可用之 radix。
			while (Number.isNaN(parseInt('1', ++MIN_RADIX)));
			try {
				for (; ; MAX_RADIX++)
					// console.log(MAX_RADIX + ' ' + DEFAULT_DIGITS);
					// will be '0123456789abcdefghijklmnopqrstuvwxyz'
					DEFAULT_DIGITS += MAX_RADIX < DEFAULT_RADIX ? MAX_RADIX.toString() : MAX_RADIX.toString(MAX_RADIX + 1);
			} catch (e) { }
			// 將 DEFAULT_DIGITS 轉成小寫。
			DEFAULT_DIGITS = DEFAULT_DIGITS.toLowerCase();
			DEFAULT_DIGITS_CACHE = digit_cache(DEFAULT_DIGITS.split(''));

			//規範 MAX_SAFE_INTEGER
			if (MAX_SAFE_INTEGER > Number.MAX_SAFE_INTEGER)
				MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER;

			//決定 determines thie MIN_BASE
			while ((MAX_SAFE_INTEGER / ++MIN_BASE | 0) < 0);

			(function () {
				// 測試 array_type 可存取 attributes。
				var a = array_type && new array_type(2), b;
				if (a)
					a[KEY_BASE] = 9;
				if (!a || a[KEY_BASE] !== 9)
					// assert: Array 可存取 attributes。
					a = new (array_type = Array);
				else if (0 < a.BYTES_PER_ELEMENT) {
					// for TypedArray, 決定 MAX_BASE。
					// 1 byte = 8 bits
					b = Math.floor(Math.sqrt(1 << 8 * a.BYTES_PER_ELEMENT));
					if (b < MAX_BASE) {
						if (a.BYTES_PER_ELEMENT < 4)
							library_namespace.warn('所使用之 array type 能存放之值過小，將影響效能！');
						MAX_BASE = b;
					} else if (MAX_BASE < b)
						// 一般說來，TypedArray 不可能存放超過 Number.MAX_SAFE_INTEGER 之整數值，因此不應該執行到這！
						library_namespace.error('所使用之 array type 能存放超過最大可安全計算整數 Number.MAX_SAFE_INTEGER 之值，恐造成錯誤計算結果！');
				}

				// 決定可用的 .push() 等 array 工具函數。
				if (array_type.prototype.push) {
					array_type.prototype.push.apply(a = new array_type, [4, 3]);
					if (a[1] === 3 && a.length === 2) {
						a.length = 0;
						if (a.length === 0) {
							//可設定 .length
							array_clone = Array_clone;
							array_reset = Array_reset;
							trim_0 = Array_trim_0;
							shift_digits = Array_shift_digits;
						}
					}
				}
				if (!array_clone) {
					array_clone = General_clone;
					//無法設定 .length
					array_reset = General_reset;
					trim_0 = function (integer) {
						return integer;
					};
					shift_digits = General_shift_digits;
				}
			})();

			// ---------------------------------------------------------------------//
			// 工具函數

			// 為正規 base。
			function valid_base(base, force_change_base) {
				// assert: MAX_BASE === MAX_BASE | 0
				if (base === (base | 0)
					//
					&& (force_change_base ? MIN_RADIX <= base : MIN_BASE <= base)
					&& base <= MAX_BASE
					//&& base !== Integer.prototype[KEY_BASE]
					)
					return base;
			}

			// 為正規 radix。
			function valid_radix(radix) {
				// assert: MIN_RADIX === MIN_RADIX | 0
				if (radix === (radix | 0)
					&& MIN_RADIX <= radix && radix <= MAX_BASE
					)
					return radix;
			}

			// 超過此界限，與元素(Integer digit)相乘時即有可能超過 Number.MAX_SAFE_INTEGER。
			// boundary(base+2)<Number.MAX_SAFE_INTEGER
			function multiplication_boundary(base) {
				// assert: return > 1
				return valid_base(base) ? Math.floor(MAX_SAFE_INTEGER / base) : MULTIPLICATION_BOUNDARY;
			}


			// 若為準確次方，則回傳次方數。
			// number = base ^ count_exponent(number, base)
			function count_exponent(number, base) {
				if (number < base)
					return -count_exponent(base, number);

				var exponent = 0;
				while (number !== 0 && 0 === number % base)
					number /= base, exponent++;
				if (number === ZERO_EXPONENT)
					return exponent;
			}

			function do_modified(integer) {
				delete integer[KEY_CACHE];
			}

			// ---------------------------------------------------------------------//
			//	definition of module integer

			/**
			 * 任意大小、帶正負號的整數。integer instance.
			 *
			 * @example
			 * <code>
			 * CeL.log((new CeL.integer('876567896')).op('*','6456789976545678'));
			 * </code>
			 *
			 * @class	Integer 的 constructor
			 * @constructor
			 */
			function Integer(number, base, to_base, force_change_base) {
				if (1 === arguments.length && is_Integer(number))
					// number = Integer(number)
					// 當純粹只是為了轉換型別時使用。
					return this instanceof Integer ? number.clone() : number;

				var integer = new_instance();
				if (number !== undefined || 1 < arguments.length)
					if (Number.isSafeInteger(number)) {
						if (MIN_RADIX <= base && !to_base || typeof to_base === 'boolean')
							// shift arguments
							force_change_base = to_base, to_base = base;
						// 快速處理常用功能。
						if (to_base = valid_base(to_base, force_change_base))
							integer[KEY_BASE] = to_base;
						else
							// assert: integer[KEY_BASE] === DEFAULT_BASE
							to_base = DEFAULT_BASE;
						if (number === 0)
							integer[0] = 0;
						else {
							if (number < 0)
								integer[KEY_NEGATIVE] = true, number = -number;
							for (var index = 0; 0 < number; number = number / to_base | 0)
								integer[index++] = number % to_base;
						}
					} else
						assignment.apply(integer, arguments);

				return integer;
			}

			//	instance public interface	-------------------

			//	每個位數存放 {safe integer} 0 – 此數-1，大於等於 此數 即須進位。
			//read-only
			Integer.prototype[KEY_BASE] = DEFAULT_BASE;
			// 預設為 0 次方。
			Integer.prototype[KEY_EXPONENT] = 0;

			// https://en.wikipedia.org/wiki/Operation_(mathematics)
			var OP_REFERENCE = {
				'+': add,
				'-': subtract,
				'*': multiply,
				'/': divide,
				'%': modulo,
				'^': power,
				'=': assignment,
				'==': compare
			};

			Object.assign(Integer.prototype, OP_REFERENCE, {
				forEach: Array.prototype.forEach,

				// 下面全部皆為 assignment，例如 '+' 實為 '+='。
				assignment: assignment,
				assign: assignment,

				// add_assignment
				add: add,
				// subtract_assignment
				subtract: subtract,
				// multiply_assignment
				multiply: multiply,
				// divide_assignment
				division: division,
				divide: divide,
				div: divide,
				modulo: modulo,
				mod: modulo,

				power: power,
				pow: power,
				square: square,
				square_root: square_root,
				sqrt: square_root,
				// 至此為 assignment。

				precise_divide: precise_divide,

				clone: clone,
				// 偶數的
				is_even: function (test_odd) {
					return !(KEY_TYPE in this) && this[KEY_EXPONENT] === 0
						//
						&& this.modulo(2) === (test_odd ? 1 : 0);
				},
				// 奇數的,單數的
				is_odd: function () {
					return this.is_odd(true);
				},

				// absolute value/絕對值/模
				// https://en.wikipedia.org/wiki/Absolute_value
				abs: function (negative) {
					if ((negative = !!negative) !== !!this[KEY_NEGATIVE])
						do_modified(this), this[KEY_NEGATIVE] = negative;
					return this;
				},
				// 變換正負號。
				negate: function () {
					do_modified(this);
					if (this[KEY_NEGATIVE])
						delete this[KEY_NEGATIVE];
					else if (!this.is_0())
						this[KEY_NEGATIVE] = true;
					return this;
				},
				is_positive: function () {
					return this.compare(0) > 0;
				},
				is_negative: function () {
					return !!this[KEY_NEGATIVE];
				},
				// 正負符號。
				// https://en.wikipedia.org/wiki/Sign_(mathematics)
				// https://en.wikipedia.org/wiki/Sign_function
				sign: function (negative) {
					// NaN: 0
					return this[KEY_NEGATIVE] ? -1 : this.is_0() ? 0 : Number.isNaN(this[KEY_TYPE]) ? undefined : 1;
				},
				get_base: function () {
					return this[KEY_BASE];
				},
				get_exponent: function (exp) {
					if (Number.isSafeInteger(exp) && exp !== this[KEY_EXPONENT]) {
						do_modified(this);
						// WARNING 注意: 除非有正當理由，否則不應直接修改 exponent！
						if (!(this[KEY_EXPONENT] = exp))
							// Can't use delete @ IE8.
							//delete this[KEY_EXPONENT];
							this[KEY_EXPONENT] = 0;
					}
					return this[KEY_EXPONENT];
				},
				expand_exponent: function () {
					//直接展開指數。直接作位元操作，以求效率。
					shift_digits(this, -this[KEY_EXPONENT], true);
					// assert: this[KEY_EXPONENT] === 0
					//去除 exponent 設定。
					// Can't use delete @ IE8.
					//delete this[KEY_EXPONENT];
					this[KEY_EXPONENT] = 0;
					return this;
				},

				Euclidean_algorithm: Euclidean_algorithm,

				to_precision: to_precision,
				round: round,
				floor: function (digits) {
					return this.round(digits, -Infinity);
				},
				ceil: function (digits) {
					return this.round(digits, Infinity);
				},

				log: log,

				is_0: is_0,
				compare_amount: compare_amount,
				compare: compare,
				equals: function (number) {
					return this.compare(number) === 0;
				},
				isFinite: function () {
					return !(KEY_TYPE in this);
				},
				isNaN: function () {
					return (KEY_TYPE in this) && isNaN(this[KEY_TYPE]);
				},

				power_modulo: power_modulo,
				Miller_Rabin: Miller_Rabin,
				not_prime: not_prime,
				Pollards_rho: Pollards_rho_1980,
				factorize: factorize,

				op: set_operate(OP_REFERENCE),
				for_each_digit: for_each_digit,

				ratio_to: ratio_to,
				valueOf: valueOf,
				digits: digits,
				digit_sum: digit_sum,
				toString: toString
			});

			// setup Integer constructor after Integer.prototype configured.
			var new_instance = Array.derive(Integer, array_type);

			//	class public interface	---------------------------

			var is_Integer = (new Integer) instanceof Integer ? function (number) {
				return number instanceof Integer;
			} : array_type === Array ? Array.isArray
			//
			: library_namespace.type_tester(library_namespace.is_type(new array_type));

			function Integer_compare(number1, number2) {
				if (typeof number1 === 'number' && typeof number2 === 'number')
					return number1 - number2;

				if (!is_Integer(number1))
					number1 = new Integer(number1, null, is_Integer(number2) && number2[KEY_BASE]);
				return number1.compare(number2);
			}

			// get the extreme value (極端值: maximum/min) of input values
			function extreme(values, get_minima) {
				var index = values.length, extreme_value, value, compare;
				if (!index)
					// ES6: Math.max: If no arguments are given, the result is −∞.
					return get_minima ? Infinity : -Infinity;

				extreme_value = values[--index];
				while (0 < index--) {
					// WARNING 注意: 當碰上許多大數時，會出現需要多次轉換 extreme_value 成 Integer 的效能低下情形!
					// 但若許多數字不同底，而最大的是 String，則可能獲得部分效能。
					if (Number.isNaN(compare = Integer_compare(extreme_value, value = values[index])))
						// ES6: Math.max: If any value is NaN, the result is NaN.
						return NaN;

					if (get_minima ? compare > 0 : compare < 0)
						extreme_value = value;

					// 依規範，必須掃描一次，確定沒 NaN。不可中途跳出。
					if (false && (get_minima ? compare > 0 : compare < 0)
						//當有改變時才偵測。
						&& typeof (extreme_value = value) === 'number' && !Number.isFinite(extreme_value = value))
						break;
				}
				return extreme_value;
			}

			// range:
			// 1 – Number.MAX_SAFE_INTEGER 當作 digits
			// Number.MAX_SAFE_INTEGER + 1 – Number.MAX_VALUE || (is_Integer(range) && !(KEY_TYPE in range)) 當作 maximum value
			// 其他採預設值 digits = 2
			function random(range, base) {
				var r, i;

				if (0 < range && isFinite(range))
					if (!Number.isSafeInteger(range = +range))
						range = new Integer(range, null, base);

				if (is_Integer(range) && !(KEY_TYPE in range)) {
					//求極值之最大位元
					for (i = range.length; 0 < i && range[--i] < 2 ;);
					if (range[i] < 2)
						range = 0;
					else {
						r = new Integer(0, base);
						r[i] = Math.floor(range[i] * Math.random());
						range = i;
					}
				}

				// 其他情況採預設值 digits = 2
				if (!(0 < range) || !Number.isSafeInteger(range))
					range = 2;

				// assert: range = {natural number}digits

				if (!r)
					r = new Integer(0, base);

				for (base = r[KEY_BASE]; 0 < range;)
					r[--range] = Math.floor(base * Math.random());

				return r;
			}

			// WARNING 注意: this operation will modify arguments!
			// https://en.wikipedia.org/wiki/Lehmer%27s_GCD_algorithm
			function Integer_GCD(number_array) {
				if (arguments.length > 1)
					// Array.from()
					number_array = Array.prototype.slice.call(arguments);

				// 盡可能先挑小的，增加效率。
				number_array.sort();

				var index = 0, length = number_array.length, number, n,
				//
				use_Number, Integer_Array = [], gcd = undefined;
				// 先嘗試是否可能找出較小的 gcd 以提升效能。
				for (; index < length;) {
					number = number_array[index++];
					if (typeof number === 'string')
						number = Number.isSafeInteger(n = parseInt(number)) ? n : new Integer(number);

					if (is_Integer(number))
						Integer_Array.push(number);
					else if (number && !(1 < (gcd = gcd === undefined ? number : GCD([number, gcd]))))
						return gcd;
				}

				for (use_Number = gcd !== undefined, index = 0, length = Integer_Array.length; index < length;) {
					number = Integer_Array[index++];
					if ((KEY_TYPE in number) || number.is_0())
						continue;
					if (gcd === undefined) {
						gcd = number;
						continue;
					}

					if (use_Number) {
						// number = number % gcd
						// assert: number.valueOf() is not Infinity
						if (number = number.modulo(gcd).valueOf()) {
							gcd = GCD([gcd, number]);
							if (gcd === 1)
								break;
						}
						//else: 整除，GCD 不變，跳過此數。

					} else {
						//if (typeof (gcd = number.Euclidean_algorithm(gcd)[1]) === 'number') use_Number = true;

						// 使用 .modulo() 以增進效率，不使用 .Euclidean_algorithm()。
						while (!number.modulo(gcd).is_0())
							//swap gcd, number.
							n = gcd, gcd = number, number = n;
						if (gcd.is_0(1)) {
							gcd = 1;
							break;
						}
						if (Number.isSafeInteger(n = gcd.valueOf()))
							gcd = n, use_Number = true;
					}
				};

				return gcd;
			}

			// https://en.wikipedia.org/wiki/Least_common_multiple
			function Integer_LCM(number_array) {
				if (arguments.length > 1)
					// Array.from()
					number_array = Array.prototype.slice.call(arguments);

				var lcm = new Integer(number_array[0]),
				//index = 1: [0] → lcm
				index = 1, length = number_array.length, number;
				// TODO: 增進效率。
				for (; index < length && lcm.compare(0) > 0 ;)
					lcm = lcm.division(lcm.clone().Euclidean_algorithm(
						// lcm = lcm / GCD * number
						is_Integer(number = number_array[index++]) ? number.clone() : number)[1])
						//
						.multiply(number);

				return lcm;
			}


			// factorial_cache[ n ] = n!
			// factorial_cache = [ 0! = 1, 1!, 2!, .. ]
			var factorial_cache = [1],
			// maximum cache length.
			// assert: (factorial_cache_limit!) 已逾越 SafeInteger 範圍， 約為 18。
			factorial_cache_limit = 80,
			factorial_SafeInteger_limit;
			/**
			 * Get the factorial (階乘) of (integer).<br />
			 * 
			 * @param {integer}integer
			 *            safe integer.
			 * @returns n的階乘.
			 * @see https://en.wikipedia.org/wiki/Factorial
			 */
			function factorial(integer) {
				if ((integer !== integer | 0) || !Number.isSafeInteger(integer)
						|| !(integer >= 0)) {
					library_namespace.error('factorial: invalid number: '
							+ integer);
					return NaN;
				}

				var length = factorial_cache.length;
				if (integer < length) {
					if (is_Integer(integer = factorial_cache[integer]))
						integer = integer.clone();
					return integer;
				}

				var f = factorial_cache[--length];
				if (!factorial_SafeInteger_limit) {
					while (length < integer)
						if (Number.isSafeInteger(f *= ++length))
							factorial_cache.push(f);
						else {
							f = factorial_cache[--length];
							factorial_SafeInteger_limit = length;
							break;
						}
					if (integer === length)
						return f;
				}

				f = new Integer(f);
				for (var l = Math.min(factorial_cache_limit, integer) ; length < l;)
					factorial_cache.push(f.multiply(++length).clone());

				while (length < integer)
					f.multiply(++length);
				return f;
			}

			// 組合數學

			/**
			 * Get the permutation (排列的可能方式數量) of (n).<br />
			 * = n! / (n - k)!<br />
			 * TODO: precision
			 * 
			 * @param {safe
			 *            integer}n: 排列的元素數量
			 * @param {safe
			 *            integer}k 排列的長度
			 * @param {safe
			 *            integer}precision
			 * 
			 * @returns {safe integer} permutation (排列的可能方式數量) of
			 *          (n).
			 * @see https://en.wikipedia.org/wiki/Permutation
			 */
			function permutation(n, k, precision) {
				if ((n !== n | 0) || !Number.isSafeInteger(n)
						|| !(n >= 0)) {
					library_namespace.error('permutation: invalid number: '
							+ n);
					return NaN;
				}

				if (isNaN(k))
					return factorial(n);
				if (!k)
					return factorial_cache[0];
				k = n - (k | 0);
				if (!(0 <= k && k < n)) {
					library_namespace.error('permutation: invalid number: '
							+ k);
					return NaN;
				}

				if (k < 2)
					return factorial(n);

				if (n <= factorial_cache_limit) {
					n = factorial(n);
					k = factorial_cache[k];
					if (is_Integer(n))
						n = n.division(k);
					else
						n /= k;
					return n;
				}

				var m, p;
				if (factorial_cache_limit < k)
					p = new Integer(++k);
				else
					m = factorial(factorial_cache_limit).division(factorial_cache[k]), p = new Integer(k = factorial_cache_limit + 1);
				while (++k <= n)
					p.multiply(k);
				if (m)
					p.multiply(m);

				return p;
			}

			// 多項式定理係數/multinomial coefficients
			// https://en.wikipedia.org/wiki/Multinomial_theorem#Multinomial_coefficients
			function multinomial_coefficient(count_array) {
				if (!Array.isArray(count_array))
					count_array = Array.prototype.slice.apply(arguments);
				// small → big
				count_array.sort();

				var c = new Integer(MULTIPLICATIVE_IDENTITY),
				//
				n = count_array.pop(), i = 0, l = count_array.length, k, p, f;
				while (i < l) {
					k = count_array[i++];
					p = permutation(n += k, k);
					f = factorial(k);
					c.multiply(typeof p !== 'number' || factorial_SafeInteger_limit < k ? Integer(p).division(f) : p / f);
				}
				return c;
			}

			// 二項式係數/組合
			// (1 + x)^n 的多項式展式中，x^k 項的係數。
			// combination(n, k) = n!/k!/(n-k)!
			// https://en.wikipedia.org/wiki/Combination
			function combination(n, k) {
				return multinomial_coefficient([k, n - k]);
			}

			// get the ratio of (length) th convergent of continued fraction.
			// 取得連分數序列(sequence)至第(length)個逼近的比例值
			// modified from data.math.continued_fraction
			// TODO: {Integer|Array}partial_numerator, {Boolean}get_coefficients, to quadratic
			function convergent_of(sequence, length, base, partial_numerator, get_coefficients) {
				if (!Array.isArray(sequence) || !sequence.length || sequence.length < 1)
					return sequence;

				if (length < 0)
					length += sequence.length;
				if (!(0 < length) || sequence.length < length)
					length = sequence.length;

				var numerator = new Integer(1), denominator = new Integer(0), i;
				if (length % 2)
					i = numerator, numerator = denominator, denominator = i;

				while (length--) {
					i = new Integer(sequence[length], base);
					if (length % 2)
						denominator.add(i.multiply(numerator));
					else
						numerator.add(i.multiply(denominator));
				}

				return [numerator, denominator];
			}


			Object.assign(Integer, {
				radix_point: function (p) {
					if (p)
						radix_point = p;
					return radix_point;
				},
				DEFAULT_BASE: DEFAULT_BASE,
				valid_radix: valid_radix,
				set_operate: set_operate,

				random: random,
				// maximum
				max: function Integer_max() {
					// get max()
					return extreme(arguments);
				},
				min: function Integer_min() {
					// get min()
					return extreme(arguments, true);
				},
				compare: Integer_compare,

				// WARNING 注意: this operation will modify both dividend and divisor!
				Euclidean_algorithm: function (dividend, divisor, get_coefficients) {
					if (!is_Integer(dividend))
						dividend = new Integer(dividend, is_Integer(divisor) && divisor[KEY_BASE]);
					return dividend.Euclidean_algorithm(divisor, get_coefficients);
				},
				GCD: Integer_GCD,
				LCM: Integer_LCM,

				// TODO: precision
				square_root: function (number, negative_exponent) {
					return (new Integer(number)).square_root(negative_exponent);
				},

				E: Integer_E,
				exp: Integer_exp,
				LN2: Integer_LN2,
				LN10: Integer_LN10,
				PI: Integer_PI,

				factorial: factorial,
				permutation: permutation,
				combination: combination,
				multinomial_coefficient: multinomial_coefficient,

				convergent_of: convergent_of,

				is_Integer: is_Integer
			});

			// ---------------------------------------------------------------------//

			// 因 clone 頗為常用，作特殊處置以增進效率。
			function clone(convert_to_Number_if_possible, target_Integer, include_cache) {
				if (convert_to_Number_if_possible === true) {
					var value = this.valueOf();
					if (value <= Number.MAX_SAFE_INTEGER) {
						return value;
					}

				} else if (typeof convert_to_Number_if_possible !== 'boolean' && include_cache === undefined) {
					// shift arguments
					include_cache = target_Integer;
					target_Integer = convert_to_Number_if_possible;
				}
				if (!is_Integer(target_Integer)) {
					target_Integer = new_instance();
				}

				[KEY_BASE, KEY_NEGATIVE, KEY_TYPE in this ? KEY_TYPE : KEY_EXPONENT].forEach(function (key) {
					if (key in this)
						target_Integer[key] = this[key];
				}, this);

				if (!(KEY_TYPE in this)) {
					array_clone(this, target_Integer);

					if (include_cache) {
						if (KEY_CACHE in this)
							// clone Array
							target_Integer[KEY_CACHE] = this[KEY_CACHE].slice();
						if (KEY_FACTORS in this)
							target_Integer[KEY_FACTORS] = this[KEY_FACTORS].slice();
					}
				}

				return target_Integer;
			}

			function get_precision(number) {
				var matched = String(number).match(/^-?(\d*)\.(\d+)$/);
				if (matched)
					return (matched[1] === '0' ? 0 : matched[1].length) + matched[2].length;
			}

			/**
			 * assignment value of integer instance.<br />
			 * 僅設定單一值。
			 *
			 * @param	{Number|String|Integer}number 輸入數值(value/number)大小。
			 * @param	{natural number|String|Array}[base]	輸入字串採用之進位制基底/數字 digit 字集。區分大小寫。僅於輸入字串時有用。
			 * @param	{natural number}[to_base]	內採基底/進位制。
			 *
			 * @example
			 * <code>
			 * CeL.log((new CeL.integer('876567896')).op('*','6456789976545678'));
			 * </code>
			 *
			 * @return	回傳 integer 物件。
			 */
			function assignment(number, base, to_base, force_change_base) {

				if (typeof number === 'number' && get_precision(number) < MAX_TRUNCATED) {
					//當可能以十進位為底做截斷時，採用十進位之值。
					//e.g., 輸入 3423.3451242354，則取 '3423.3451242354'，而非 3423.34512423539990778081119060516357421875。
					number = number.toString();
					// shift arguments
					force_change_base = to_base;
					to_base = base;
					base = DEFAULT_RADIX;
				}

				/**
				 * 前期處理: String → Number / Integer<br />
				 * 轉換指定進位的數字文字，成為{Number}純量或 {Integer} 物件。<br />
				 * treat arguments as: (number_String, base, to_base)
				 *
				 * @see
				 * <a href="https://en.wikipedia.org/wiki/Numerical_digit" accessdate="2010/4/16 20:47">Numerical digit</a>
				 */
				if (typeof number === 'string' && (number = number.trim())) {
					// 正規化(normalize) base

					// {Array}base → {String}base
					if (Array.isArray(base)) {
						base.forEach(function (digit) {
							if (digit.length !== 1)
								library_namespace.error('assignment: Invalid digit of base: [' + digit + '].');
						});
						base = base.join('');
					}
					if (typeof base === 'string' && DEFAULT_DIGITS.startsWith(base.toLowerCase()))
						// 使用 DEFAULT_DIGITS。
						base = base.length;

					if (typeof base === 'string' ? base.length < 2
						//base is number
						: !valid_radix(base)) {
						if (base)
							library_namespace.error('assignment: Invalid base: [' + base + ']');
						base = undefined;
					}

					var digits, value;

					if (value = number.match(PATTERN_HEX))
						number = value[1], base = HEX_RADIX;

					if (typeof base === 'string') {
						digits = digit_cache(base.split(''));
						value = number.split('');
						number = new Integer(0, base = base.length);


						// 使用 DEFAULT_DIGITS。不分大小寫(將轉成小寫)。基本上應與 parseInt() 一致。
						//	[ full , sign, integer part 整數部分, fractional part 小數部分, decimal exponent 指數, percent ]
					} else if (value = (value = number.toLowerCase()).match(PATTERN_NUMBER)
						//
						|| value.match(PATTERN_NUMBER_HEX)) {
						if (!base)
							base = DEFAULT_RADIX;
						number = new Integer(0, base);
						//處理 minus sign
						if (value[1] === '-')
							number[KEY_NEGATIVE] = true;
						//處理指數
						value[4] |= 0;
						if (value[3]) {
							//處理掉 fractional part 小數部分
							value[4] -= value[3].length;
							value[2] += value[3];
						}
						if ((digits = value[2].match(/^(.*)(0+)$/))
							//1e4: 若是 exponent 不大，則基本上無須處理，直接展開即可。
						&& (value[4] < 0 || 1e4 < value[4] + digits[2].length)) {
							//去掉最後的 0
							value[4] += digits[2].length;
							value[2] = digits[1];
						}
						if (value[5])
							value[4] += exponent_parts_per[value[5]];
						if (value[4])
							//1e4: 若是 exponent 不大，則基本上無須處理，直接展開即可。
							if (value[4] < 0 || 1e4 < value[4])
								number[KEY_EXPONENT] = value[4];
							else
								value[2] += '0'.repeat(value[4]);

						//去掉起頭的 '0'。
						value = value[2].replace(/^0+/, '').split('');
						digits = DEFAULT_DIGITS_CACHE;


						// 死馬當活馬醫，嘗試以 native method 取得。
						// 若非十進位又包含 radix_point，則跳過。
					} else if (//(!base || base !== DEFAULT_RADIX || number.indexOf(radix_point) === -1) &&
						Number.isSafeInteger(value = base ? parseInt(number, base) : parseFloat(number)))
						number = value;


					else {
						library_namespace.error('assignment: Invalid number string: [' + number + '].');
						number = NaN;
					}

					if (Array.isArray(value)) {
						//base: {natural number}length of base.
						//digits: {Object}base cache.
						//value: {Array}digits of specified base
						// number: 欲轉換 base 之 {Integer}。

						value.reverse();
						// Array.map()
						value.forEach(function (digit, index) {
							if (digit in digits)
								number[index] = digits[digit];
							else
								library_namespace.error('assignment: Invalid number digit: [' + digit + '].');
						});
						if (!to_base && count_exponent(DEFAULT_BASE, base))
							to_base = DEFAULT_BASE;
					}

				} else if (MIN_RADIX <= base && !to_base || typeof to_base === 'boolean')
					// shift arguments
					force_change_base = to_base, to_base = base, base = undefined;

				// ---------------------------------------
				if (is_Integer(number)) {
					// 已經是 Integer 了。
					// clone, deep_copy。

					//let to_base === this[KEY_BASE], base === number[KEY_BASE]
					// 無設定 to_base 時，將 base 視作 to_base。
					// assert: number[KEY_BASE] 為正規 base。
					to_base = valid_base(to_base, force_change_base) || number[KEY_BASE];
					base = number[KEY_BASE];

					if (this !== number || base !== to_base) {
						if (this === number)
							number = number.clone();
						else {
							// copy attributes.
							this[KEY_NEGATIVE] = number[KEY_NEGATIVE];

							if (KEY_CACHE in number) {
								var array = this[KEY_CACHE] = [];
								number[KEY_CACHE].forEach(function (string, radix) {
									array[radix] = string;
								});
							} else
								delete this[KEY_CACHE];

							if (KEY_FACTORS in number) {
								var array = this[KEY_FACTORS] = [];
								number[KEY_FACTORS].forEach(function (factor) {
									if (factor)
										array.push(is_Integer(factor) ? factor.clone() : factor);
								});
							} else
								delete this[KEY_FACTORS];
						}

						do_modified(this);

						this[KEY_BASE] = to_base;

						if (KEY_TYPE in number) {
							//處理特殊值。
							this[KEY_TYPE] = number[KEY_TYPE];
							// Can't use delete @ IE8.
							//delete this[KEY_EXPONENT];
							this[KEY_EXPONENT] = 0;
							array_reset(this);

						} else if (to_base === base || number.length < 2 && !(to_base <= number[0])) {
							//處理簡易數值。
							if (number[KEY_EXPONENT])
								this[KEY_EXPONENT] = number[KEY_EXPONENT];
							else
								// Can't use delete @ IE8.
								//delete this[KEY_EXPONENT];
								this[KEY_EXPONENT] = 0;
							array_clone(number, this);

						} else {
							// change base to / set base / 數字基底的轉換。
							// https://en.wikipedia.org/wiki/Change_of_base
							// https://en.wikipedia.org/wiki/Base_conversion

							var exponent = count_exponent(to_base, base), to_digit_Array = array_reset(this),
							scalar = 0,
							base_now = ZERO_EXPONENT;

							// 對 exponent 做特殊處置，增進效率。
							if (0 < exponent) {
								// e.g., base 10 → to_base 100
								if (number[KEY_EXPONENT]) {
									//因為會改變 number，因此新造一個。
									number = number.clone();
									if (0 < number[KEY_EXPONENT]) {
										// e.g., base=1e1, to_base=1e7, 23e(+17*1) = 23000e(+2*7)
										this[KEY_EXPONENT] = number[KEY_EXPONENT] / exponent | 0;
										shift_digits(number, -number[KEY_EXPONENT] % exponent);
									} else {
										// e.g., base=1e1, to_base=1e7, 23e(-17*1) = 230000e(-3*7)
										this[KEY_EXPONENT] = (number[KEY_EXPONENT] / exponent | 0) - 1;
										shift_digits(number, -(number[KEY_EXPONENT] % exponent) - exponent);
									}
								}

								number.forEach(function (digit, index) {
									scalar += digit * base_now;
									if ((index + 1) % exponent === 0)
										to_digit_Array.push(scalar), scalar = 0, base_now = ZERO_EXPONENT;
									else
										base_now *= base;
								});
								if (scalar)
									to_digit_Array.push(scalar);
								array_clone(to_digit_Array, this);

							} else if (exponent < 0) {
								// e.g., base 100 → to_base 10
								exponent = -exponent;
								if (number[KEY_EXPONENT])
									// e.g., base=1e7, to_base=1e1, 2300e(+2*7) = 2300e(+14*1)
									// e.g., base=1e7, to_base=1e1, 2300e(-2*7) = 2300e(-14*1)
									this[KEY_EXPONENT] = exponent * number[KEY_EXPONENT];
								number.forEach(function (digit, index) {
									for (var i = 0; i < exponent; i++)
										to_digit_Array.push(digit % to_base), digit = digit / to_base | 0;
								});
								trim_0(to_digit_Array);
								array_clone(to_digit_Array, this);

							} else if (1 === (exponent = Math.log(MAX_BASE) / Math.log(to_base) | 0)) {
								//無法做特殊處置時之一般性處理。
								var fraction = 0, index, boundary = multiplication_boundary(to_base);

								if (number[KEY_EXPONENT]) {
									//因為會改變 number，因此新造一個。
									number = number.clone();
									if (0 < number[KEY_EXPONENT])
										//直接展開指數。
										number.expand_exponent();
									else {
										library_namespace.error('assignment: Unable to convert from base ' + base + ' to base ' + to_base + ' with exponent ' + number[KEY_EXPONENT] + ' without loss of significance.');
										//計算 fraction。
										index = -number[KEY_EXPONENT];
										for (var fraction_base = ZERO_EXPONENT; fraction_base && index;)
											fraction += number[--index] * (fraction_base /= base);
										//直接展開指數。去掉 fraction。
										number.expand_exponent();
									}
								}

								//reset (this)
								array_clone([0], this);

								index = number.length;
								while (0 < index--) {
									base_now *= base;
									scalar = scalar * base + number[index];
									if (boundary < base_now * base || index === 0) {
										this.for_each_digit(function (digit, carry, index) {
											// 除了積本身，這邊可能出現 scalar<=(boundary-1), carry<=(base-1)。
											// (base-1)*boundary+(boundary-1)+(base-1) <= Number.MAX_SAFE_INTEGER
											// This is also the limit of (base), therefore:
											// MAX_BASE<=Math.sqrt(Number.MAX_SAFE_INTEGER+2),
											// boundary<=(Number.MAX_SAFE_INTEGER+2)/base-1,
											return digit * base_now + carry + (index ? 0 : scalar);
										});
										//reset
										scalar = 0, base_now = ZERO_EXPONENT;
									}
								}

								if (fraction)
									this.add(fraction, this[KEY_NEGATIVE]);

								if (0 === number.length)
									// assert: Array.(number)
									number.push(0);

							} else
								//盡可能把 to_base 加大，減少 call .for_each_digit() 的次數，以增進效率。
								this.assignment(new Integer(number, Math.pow(to_base, exponent)), to_base, force_change_base);
						}
					}

					// ---------------------------------------
				} else {
					if (typeof number !== 'number') {
						library_namespace.error('assignment: Invalid value to assignment: [' + number + '].');
						number = NaN;
					}

					if (base !== to_base
						//
						|| this.compare(number) !== 0) {
						do_modified(this);

						// value/scalar純量 to digit Array.
						// treat arguments as: (number, do not set fraction = false, to_base)

						// 對於非數字，無法斷定。
						if (number < 0)
							number = -number,
							this[KEY_NEGATIVE] = true;
						else
							delete this[KEY_NEGATIVE];

						delete this[KEY_FACTORS];
						// Can't use delete @ IE8.
						//delete this[KEY_EXPONENT];
						this[KEY_EXPONENT] = 0;

						if (!isFinite(number)) {
							//NaN, Infinity, -Infinity
							this[KEY_TYPE] = number;
							array_reset(this);

						} else {
							delete this[KEY_TYPE];
							//to_base 實為欲轉換之標的 base。
							if (to_base = valid_base(to_base, force_change_base))
								this[KEY_BASE] = to_base;
							else
								to_base = this[KEY_BASE];
							//base 實為是否不轉換小數部分。
							if (base && number !== Math.floor(number)) {
								//number 有小數部分。
								library_namespace.warn('assignment: Number has a fractional part: [' + number + '].');
								number = Math.floor(number);
							}
							if (number < to_base && number === (number | 0))
								// 僅設定scalar純量部份。
								array_clone([number], this);

							else {
								var digit_Array = array_reset(this);

								// assert: 1 < to_base
								if (number !== Math.floor(number)) {
									// 當 base_now === 0，表示系統已無法處理較這更小的數字，再保留這之下的數值已無意義。
									for (var base_now = ZERO_EXPONENT, remainder = number % 1; remainder && (base_now /= to_base) ;)
										digit_Array.unshift((remainder *= to_base) | 0), remainder %= 1;
									this[KEY_EXPONENT] = -digit_Array.length;
									number = Math.floor(number);
								} else if (!Number.isSafeInteger(number))
									//test only
									library_namespace.warn('assignment: Number is too large: [' + number + '].');

								while (0 < number) {
									digit_Array.push(number % to_base);
									number = Math.floor(number / to_base);
								}
								array_clone(digit_Array, this);
							}
						}
					}
				}

				return this;
			}


			function get_test_value(number) {
				return is_Integer(number) ? number.valueOf(TYPE_TEST) : +number;
			}


			// little_natural: little natural number < MIN_RADIX, e.g., 1
			function is_0(little_natural) {
				return !(KEY_TYPE in this) && this.length < 2 && (little_natural ? !this[KEY_EXPONENT] && this[0] === little_natural : !this[0]);
			}

			/**
			 * 測試大小/比大小。僅比較量之大小，忽略符號。
			 * @param number	the number to compare
			 * @return	{Number}	0:==, <0:<, >0:>
			 * @_name	_module_.prototype.compare_to
			 */
			// return < 0 : this < number
			// return === 0 : this === number
			// return > 0 : this > number
			// return others : invalid number
			function compare_amount(number) {
				if (this === number)
					return 0;

				var i = typeof number === 'string' ? 0 : get_test_value(number), l, d;
				if ((KEY_TYPE in this) || !isFinite(i))
					// NaN 等極端數字的情形。
					return Math.floor(this[KEY_TYPE]) - Math.floor(i);

				// 強制轉成同底的 Integer 再處理。
				if (!is_Integer(number) || this[KEY_BASE] !== number[KEY_BASE])
					number = new Integer(number, null, this[KEY_BASE]);

				i = this.length;
				// 處理 [KEY_EXPONENT]
				d = this[KEY_EXPONENT] - number[KEY_EXPONENT];
				l = i + d - number.length;
				if (!l)
					//找到第一個兩者不同的位數。
					while (0 < i-- && !(l = (this[i] || 0) - (number[i + d] || 0)));

				return l;
			}

			/**
			 * 測試大小/比大小
			 * @param number	the number to compare
			 * @return	{Number}	0:==, <0:<, >0:>
			 * @_name	_module_.prototype.compare_to
			 */
			function compare(number) {
				var c = typeof number === 'string' ? 0 : get_test_value(number);
				if ((KEY_TYPE in this) || !isFinite(c))
					// NaN 等極端數字的情形。
					return this[KEY_TYPE] - c;

				if (!is_Integer(number)) {
					if (typeof number === 'number' && this.length < 3
						//2: Math.min(-Math.floor(Math.log(Number.EPSILON) / Math.log(MAX_BASE), Math.floor(Math.log(Number.MAX_VALUE) / Math.log(MAX_BASE)) + 1))
						//預防 overflow or underflow.
						&& Math.abs(this[KEY_EXPONENT]) < 2)
						return this.valueOf() - number;
					number = new Integer(number, null, this[KEY_BASE]);
				}

				if (this[KEY_NEGATIVE] ^ number[KEY_NEGATIVE])
					return this[KEY_NEGATIVE] ? -1 : 1;

				c = this.compare_amount(number);
				return this[KEY_NEGATIVE] ? -c : c;
			}


			// 工具函數
			// 將有問題的數字全部作正確進位。
			// e.g., [10, 11].base = 10 → [0, 2, 1]
			function normalize_handle(digit, carry) {
				return digit + carry;
			}
			function normalize_digits(integer) {
				integer.for_each_digit(normalize_handle);
			}


			// 工具函數
			// 將 this integer instance 自低位依 callcack() 處理至高位，
			// 結果存至 target_Integer[跳過 target_shift 個] || this。
			// 可自動處理進退位。無法處理 overflow 問題。
			// assert: callcack() 任一回傳，皆 isSafeInteger() === true。
			function for_each_digit(callcack, target_Integer, target_shift) {
				if (!target_Integer)
					target_Integer = this;
				target_shift |= 0;

				var base = target_Integer[KEY_BASE], carry = 0, length = this.length, index = 0, digit;
				if (!Number.isSafeInteger(base))
					library_namespace.error('for_each_digit: Invalid base: [' + base + '].');

				for (; index < length || carry !== 0 ; index++, target_shift++)
					// 當 index >= length，僅作進位處理。
					if (typeof (digit = index < length ? callcack(this[index] || 0, carry, index)
						// 當 this 皆 callcack() 過後，僅處理進退位。
						: carry + (target_Integer[target_shift] || 0)) === 'number') {
						if (base <= digit) {
							// 處理進位。
							// assert: 0 < (digit / base | 0)
							// MIN_BASE: 因為用 `|0`，故 base < 5 會出現問題:
							// (Number.MAX_SAFE_INTEGER / 4 | 0) < 0, 0 < (Number.MAX_SAFE_INTEGER / 5 | 0)
							carry = digit / base | 0;
							digit %= base;
						} else if (digit < 0 && (index < length || target_shift < target_Integer.length)) {
							// 處理退位。
							carry = digit / base | 0;
							//確保 digit >=0
							if ((digit %= base) < 0)
								carry--, digit += base;
						} else
							carry = 0;
						target_Integer[target_shift] = digit;
					} else
						carry = 0;

				trim_0(target_Integer);

				if (carry)
					library_namespace.error('for_each_digit: carry [' + carry + '] left.');
				return carry;
			}

			// ---------------------------------------------------------------------//
			//四則運算，即加減乘除， + - * / (+-×÷)**[=]
			// https://en.wikipedia.org/wiki/Elementary_arithmetic

			// Addition 和: addend + addend = sum
			function add(addend, is_subtract) {
				// test if addend is zero.
				if (Number.isNaN(this[KEY_TYPE]) || get_test_value(addend) === 0)
					return this;

				// 強制轉成同底的 Integer 再處理。
				if (!is_Integer(addend) || this[KEY_BASE] !== addend[KEY_BASE])
					addend = new Integer(addend, null, this[KEY_BASE]);

				// assert: is_Integer(addend)

				if ((KEY_TYPE in this) || (KEY_TYPE in addend)) {
					addend = addend.valueOf(TYPE_TEST);
					// do simulation: 模擬與 NaN 等極端數字作運算。
					addend = this.valueOf(TYPE_TEST) + (is_subtract ? -addend : addend)
					if (addend !== this.valueOf(TYPE_TEST))
						this.assignment(addend);
					return this;
				}

				// 至此特殊值處理完畢。
				do_modified(this);

				var reverse = (is_subtract ^= this[KEY_NEGATIVE] ^ addend[KEY_NEGATIVE])
				//當兩數正負不同，且 abs(this) < abs(addend) 時，即需要反向，
				//將 addend 放在前項，改成 this = (addend - this)。
				&& this.compare_amount(addend) < 0,
				//
				shift = addend[KEY_EXPONENT] - this[KEY_EXPONENT];

				if (reverse)
					this[KEY_NEGATIVE] = !this[KEY_NEGATIVE];

				if (shift < 0)
					//為了位數對齊，須補足不足的位數。
					shift_digits(this, shift), shift = 0;

				addend.for_each_digit(
					// (addend digit, carry, index of addend)
					(reverse ? function (d, c, i) { return c + d - (this[i + shift] || 0); }
						: is_subtract ? function (d, c, i) { return c + (this[i + shift] || 0) - d; }
						: function (d, c, i) { return c + (this[i + shift] || 0) + d; }).bind(this)
					, this,
					//位數對齊。
					shift);

				if (this[KEY_NEGATIVE] && !this.valueOf(TYPE_TEST))
					//0, NaN
					delete this[KEY_NEGATIVE];

				return this;
			}

			// Subtraction 差: minuend − subtrahend = difference
			function subtract(subtrahend) {
				return this.add(subtrahend, true);
			}



			// 乘除法之先期處理。
			//@inner
			function multiply_preprocess(integer, number, is_division) {
				if (integer === number)
					throw new Error('multiply_preprocess: Same operand!');

				var value = get_test_value(number);
				// NaN (+-×÷) number = NaN
				if (Number.isNaN(integer[KEY_TYPE])
					// test if number is MULTIPLICATIVE_IDENTITY.
					|| value === MULTIPLICATIVE_IDENTITY && (!is_division || !integer[KEY_EXPONENT]))
					return;

				if (value === -MULTIPLICATIVE_IDENTITY && (!is_division || !integer[KEY_EXPONENT])) {
					//Be sure not 0, NaN.
					if (integer.valueOf(TYPE_TEST))
						integer.negate();
					return;
				}

				if (!is_Integer(number) || integer[KEY_BASE] !== number[KEY_BASE])
					// 強制轉成同底的 Integer 再處理。
					number = new Integer(number, null, integer[KEY_BASE]);

				if (value === ABSORBING_ELEMENT
					//
					|| (KEY_TYPE in integer) || (KEY_TYPE in number)
					//
					|| integer.is_0(ABSORBING_ELEMENT)) {
					// do simulation: 模擬與 NaN 等極端數字作運算。
					var v = integer.valueOf(TYPE_TEST), r;
					if (is_division) {
						r = v / value;
						value = v % value;
					} else
						value = v * value;
					if (value !== v)
						integer.assignment(value);
					return r;
				}

				// 至此特殊值處理完畢。
				do_modified(integer);

				return number;
			}


			// test:
			// check base & value: Integer (test if .is_safe_integer(true)===0, ±1, NaN)
			// show error and exit: NaN, ±Infinity
			// exit: 1
			// set sign and exit: -1
			// set value and exit: 0
			// translate to Integer: safe integer(e.g., 123), 1.23e123, '123'+'4'.repeat(400), '123'+'4'.repeat(16); the string type & negative
			// has a fractional part (有小數部分): .123, 1.123, 1903719924734991.36479887; the string type & negative; '123'+'4'.repeat(16)+'.1234'

			// 在前兩位數以上皆相同時，方可考慮採用 a × b = ((a+b)/2)^2 - ((a-b)/2)^2。

			// Multiplication 乘: multiplicand × multiplier = product
			// TODO: https://en.wikipedia.org/wiki/F%C3%BCrer%27s_algorithm
			// TODO: precision
			function multiply(multiplier, /* TODO */ precision) {
				if (multiplier = multiply_preprocess(this, multiplier)) {
					//特殊值已於 multiply_preprocess() 處理過。

					// copy factors, cache 用
					if (!(KEY_FACTORS in this))
						this[KEY_FACTORS] = [];
					this[KEY_FACTORS].push(multiplier);

					this[KEY_EXPONENT] += multiplier[KEY_EXPONENT];

					//一般乘法

					//	scalar * this，結果放在 target_digit_Array。
					var target_digit_Array = [];
					target_digit_Array[KEY_BASE] = this[KEY_BASE];

					// assert: multiplier 任一元素與 this 任一元素相乘，皆 isSafeInteger() === true。
					multiplier.forEach(function (scalar, shift) {
						if (scalar)
							this.for_each_digit(function (digit, carry, index) {
								// assert: target_digit_Array[] is natural number < base
								// 除了積本身，這邊可能出現 carry<=(base-2), target_digit_Array[]<=(base-1), 共 (2*base-3)。
								// assert: Number.isSafeInteger(base*base-2)
								// therefore: base<=Math.sqrt(Number.MAX_SAFE_INTEGER+2)
								return digit * scalar + carry + (target_digit_Array[index + shift] || 0);
							}, target_digit_Array, shift);
					}, this);

					//回存。
					array_clone(target_digit_Array, this);

					//預防中空跳號。
					if (Array.isArray(this)) {
						var index = this.length;
						while (0 < index--)
							if (this[index] === undefined)
								this[index] = 0;
					}

					if (multiplier[KEY_NEGATIVE])
						this.negate();
				}

				return this;
			}

			var REVERSE_REMAINDER = -2;
			// this → remainder。
			// return {digit Array}quotient
			// https://en.wikipedia.org/wiki/Euclidean_division
			// https://en.wikipedia.org/wiki/Division_algorithm
			function division(denominator, negative_exponent, get_nearest) {
				if (!is_Integer(denominator = multiply_preprocess(this, denominator, true))) {
					if (denominator === undefined)
						// denominator == ±1
						if (Number.isNaN(this[KEY_TYPE]))
							// NaN (+-×÷) number = NaN
							denominator = NaN;
						else if (get_test_value(this)) {
							// integer / ±1 = ±d, remainder 0.
							denominator = this.clone();
							this.assignment(0);
						} else
							denominator = 0;
					return denominator;
				}


				if (Number.isSafeInteger(negative_exponent |= 0)
					&& 0 < (negative_exponent -= denominator[KEY_EXPONENT])
					// 不減低精度，因此不處理負數。
					&& 0 < (negative_exponent += this[KEY_EXPONENT]))
					shift_digits(this, -negative_exponent);

				// (dividend or numerator) ÷ (divisor or denominator) = quotient + remainder / denominator
				var numerator = this, base = this[KEY_BASE], quotient = new Integer(0, base),
				// N: the highest digits of numerator.
				// D: the highest digits of denominator.
				N, NI, D, DI, Q, next_N, next_D;

				quotient[KEY_EXPONENT] = this[KEY_EXPONENT] - denominator[KEY_EXPONENT];

				// When denominator is bigger than numerator, the quotient will be 0 and the remainder will be numerator itself.
				while (0 < (DI = denominator.length) && DI <= (NI = numerator.length)) {
					// Get ths first non zero digit D of denominator.
					// 使用 while 的原因:對 Uint32Array 之類無法保證前幾位不為 0。
					while (!(D = denominator[--DI]) && 0 < DI);

					// Get ths first non zero digit N of numerator.
					while (!(N = numerator[--NI]) && 0 < NI);
					// 多取一位 numerator，確保 N > D。
					if (N <= D && 0 < NI && DI < NI)
						N = N * base + numerator[--NI];

					if (NI < DI || N < D)
						break;
					// assert: N >= D, NI >= DI

					//決定 determines Q = thie next digit of quotient
					// assert: (N + 1) / D === (Math.floor((N + 1) / D) | 0)
					if (DI === 0)
						//There is no digits of denominator lefting. The quotient digit has no other possibility.
						Q = N / D | 0;
					else
						//考慮兩個因素:
						//N, D 將在 Number.isSafeInteger() 的範圍內，一直乘到 N/(D+.99999~)|0===(N+.99999~)/D|0 為止。此兩數為當前 quotient 最高位數之可能值範圍。
						while (((Q = N / (D + 1) | 0) < ((N + 1) / D | 0))
							//
							&& 0 < DI
							&& Number.isSafeInteger(next_N = N * base + numerator[NI - 1])
							&& Number.isSafeInteger(next_D = D * base + denominator[DI - 1])) {
							N = next_N; NI--;
							D = next_D; DI--;
						}

					// 通常發生在 numerator 極為接近 denominator 之 Q 或 Q+1 倍時，會無法判別應該用 Q 或 Q+1。
					if (Q === 0) {
						// assert: numerator, denominator 前面幾位大小相同。
						// assert: index of quotient Array === NI - DI，尚未 borrowed。
						// 確認 numerator, denominator 孰大孰小。
						if (N === D)
							while (0 < DI && numerator[--NI] === denominator[--DI]);
						if (N < D || numerator[NI] < denominator[DI])
							if (--NI < DI)
								// numerator now (= remainder) < denominator
								break;
							else
								Q = base - 1;
						else
							// 剛好足夠減一。
							Q = 1;
					}

					//NI → index of quotient Array, the diff of numerator and denominator.
					NI -= DI;
					quotient[NI] = (quotient[NI] || 0) + Q;

					//numerator → remainder
					// numerator -= Q * denominator * base ^ (index of quotient Array = NI)
					denominator.for_each_digit(function (digit, carry, index) {
						// assert: numerator[index + NI] >= 0, carry <= 0, digit <= 0, Q > 0
						return carry + (numerator[index + NI] || 0) - Q * digit;
					}, numerator, NI);
					// assert: numerator >= 0
				}

				if (get_nearest && base <= 2 * this.at(-1)) {
					quotient[0]++;
					if (get_nearest === REVERSE_REMAINDER) {
						N = base;
						this.for_each_digit(function (digit, carry, index) {
							return (index ? N : N--) - digit + carry;
						});
					}
				}

				//處理需要進位的情況。雖然不常見，偶爾還是會發生，甚至連續進位，因此到最後才一次處理。
				normalize_digits(quotient);

				// remainder 不受 denominator 正負影響。
				// quotient 受 denominator 正負影響。
				if (quotient.valueOf(TYPE_TEST))
					// quotient is not 0 or NaN
					//e.g., 4/-5
					quotient[KEY_NEGATIVE] = this[KEY_NEGATIVE] ^ denominator[KEY_NEGATIVE];

				if (!this.valueOf(TYPE_TEST))
					// remainder is not 0 or NaN
					delete this[KEY_NEGATIVE];

				// this → remainder,
				// return {digit Array}quotient
				return quotient;
			}

			// Division 除: dividend ÷ divisor = quotient
			function divide() {
				return this.assignment(division.apply(this, arguments));
			}

			function modulo(modulus) {
				//if (KEY_TYPE in this) this.assignment(NaN); else
				if (Number.isSafeInteger(modulus) && !(KEY_TYPE in this) && !this[KEY_EXPONENT]) {
					// https://zh.wikipedia.org/wiki/%E6%95%B4%E9%99%A4%E8%A7%84%E5%88%99
					var base = this[KEY_BASE] % modulus,
					base_remainder = ZERO_EXPONENT, remainder = 0, index = 0;
					do {
						// 可於最後幾位判別。
						if (this[index]) {
							remainder += this[index] * base_remainder;
							remainder %= modulus;
						}
						if (base !== 1)
							base_remainder = base_remainder * base % modulus;
					} while (++index < this.length && 0 !== base_remainder);
					this.assignment(this[KEY_NEGATIVE] ? -remainder : remainder);

				} else
					division.apply(this, arguments);

				return this;
			}

			// 模反元素, modular multiplicative inverse
			// https://en.wikipedia.org/wiki/Modular_multiplicative_inverse
			function modular_inverse(modulus) {
				return result = this.clone().Euclidean_algorithm(modulus, true);
				if (result[1] === MULTIPLICATIVE_IDENTITY)
					return result[2];
			}

			// assert: GET_OBJECT 並非正規 radix.
			var GET_OBJECT = 1;
			// precise divide, to repeating decimal
			// radix === GET_OBJECT: get {Integer} object instead of {String}
			// return [ integer part, non-repeating fractional part, period (repeating decimal part) ]
			// https://en.wikipedia.org/wiki/Repeating_decimal
			function precise_divide(DENOMINATOR, radix, period_limit) {
				if (!DENOMINATOR)
					return [NaN, '', ''];

				if (radix !== GET_OBJECT && !valid_radix(radix))
					radix = DEFAULT_RADIX;

				if (DENOMINATOR == MULTIPLICATIVE_IDENTITY)
					return [radix === GET_OBJECT ? this : this.toString(radix), '', ''];

				// 不改變 this, DENOMINATOR
				DENOMINATOR = (new Integer(DENOMINATOR, null, this[KEY_BASE])).expand_exponent();
				var REMAINDER = this.clone().expand_exponent(), return_Array, gcd;
				if (DENOMINATOR[KEY_NEGATIVE]) {
					delete DENOMINATOR[KEY_NEGATIVE];
					REMAINDER[KEY_NEGATIVE] = !REMAINDER[KEY_NEGATIVE];
				}
				return_Array = REMAINDER.division(DENOMINATOR);

				if (radix !== GET_OBJECT)
					return_Array = return_Array.toString(radix);
				return_Array = [return_Array];
				if (REMAINDER.is_0()) {
					return_Array.push('', '');
					return return_Array;
				}

				if ((gcd = Integer_GCD(REMAINDER.abs().clone(), DENOMINATOR.clone())) !== 1)
					REMAINDER = REMAINDER.division(gcd), DENOMINATOR = DENOMINATOR.division(gcd);

				// assert: GCD(REMAINDER, DENOMINATOR) = 1, 0 < REMAINDER < DENOMINATOR, DENOMINATOR[KEY_EXPONENT] = 0.
				// e.g., 67/300 = 0.2233333...
				//radix: 10
				//F: non-repeating fractional part, '22'
				//f: digits of F, 2
				//R: 循環節 period (repeating decimal part), '3'
				//r: digits of R, 1
				//[FR]: the concatenation of F and R, '223'

				// 原理:
				// REMAINDER / DENOMINATOR = F / radix^f + R / (radix^f (radix^r - 1)) = ([FR] - F) / (radix^f (radix^r - 1))
				// radix^f (radix^r - 1) REMAINDER = ([FR] - F) DENOMINATOR
				// radix^(f+r) * REMAINDER / DENOMINATOR = [FR] + R / (radix^r - 1)
				// floor(radix^(f+r) * REMAINDER / DENOMINATOR) = [FR] = radix^r * F + R

				// 找出 f:
				// 因 GCD( DENOMINATOR, radix^f ) == GCD( DENOMINATOR, radix^(f+1) ) * d，可以此找出 f。
				// 令 d = DENOMINATOR / GCD( DENOMINATOR, radix^f )，為去掉所有 radix 因數之 DENOMINATOR。
				// 找出 r:
				// 再測試得 d | 99..9 (共 r 位)

				// 計算出 F, R:
				// 令 remainder = floor(radix^(f+r) * REMAINDER / DENOMINATOR) = [FR] = radix^r * F + R，則
				// F = remainder.slice(r),
				// R = remainder.slice(0, r).

				DENOMINATOR = new Integer(DENOMINATOR, radix);
				var d = DENOMINATOR.clone(), f = 0, r = new Integer(0, radix);
				//r → (10) in radix
				r[1] = 1;

				// 找出 f:
				// TODO: 增進效率。
				while ((gcd = Integer_GCD(d.clone(), r.clone())) !== 1)
					f++, d = d.division(gcd);

				// 找出 r:
				if (d.is_0(1))
					//is terminating decimal
					r = 0;
				else {
					// 測得 d | (remainder = 99..9) (共 r 位)
					//得先取與 d 相同之位數，保證 d <= remainder
					var remainder = new Integer(0, radix), highest = parseInt('10', radix) - 1;
					if (Array.isArray(d)) {
						//快捷方法。
						remainder.length = r = d.length;
						//fill up with highest digit
						remainder.fill(highest);
					} else {
						r = d.length;
						//確認 nonzero 之最高位。
						while (0 < r && d[--r] === 0);
						gcd = r;
						while (0 < gcd)
							//fill up with highest digit
							remainder[--gcd] = highest;
					}
					//若可能，嘗試簡化計算:將 d 轉成 {Number}。
					if (Number.isSafeInteger((gcd = d.valueOf()) * radix)) {
						remainder = remainder.modulo(d = gcd).valueOf();
						var limit = period_limit || 1e6;
						while ((remainder %= d) !== 0) {
							//未能整除。
							if (++r > limit) {
								// TODO: 盡量取得可得位數。
								library_namespace.error('precise_divide: The period of repeating decimal is too long (large than ' + limit + ')!');
								return;
							}
							//remainder + 1 <= d
							remainder = (remainder + 1) * radix - 1;
						}
					} else {
						var limit = period_limit || 1e4;
						while (!remainder.modulo(d).is_0()) {
							//未能整除。
							if (++r > limit) {
								// TODO: 盡量取得可得位數。
								library_namespace.error('precise_divide: The period of repeating decimal is too long (large than ' + limit + ')!');
								return;
							}
							shift_digits(remainder, -1, true);
							//fill up with highest digit
							remainder[0] = highest;
						}
					}
				}

				// 計算出 F, R:
				// assert: -f -r < 0, =0 的已在之前處理完畢。
				shift_digits(REMAINDER = new Integer(REMAINDER, radix), -f - r, true);
				REMAINDER = REMAINDER.division(DENOMINATOR);
				// assert: REMAINDER.length === f + r
				if (f) {
					if (r) {
						//作截斷處理。
						shift_digits(f = REMAINDER.clone(), r, true);
					} else
						f = REMAINDER;
					if (radix !== GET_OBJECT)
						f = f.toString(radix);
				}
				if (r) {
					if (f)
						//作截斷處理。
						if (Array.isArray(REMAINDER))
							REMAINDER.length = r;
						else
							while (r < REMAINDER.length)
								REMAINDER[r++] = 0;
					r = REMAINDER;
					if (radix !== GET_OBJECT)
						r = r.toString(radix);
				}
				return_Array.push(f || '', r || '');
				return return_Array;
			}


			// ---------------------------------------------------------------------//

			//最後會保留 digits 位數(in this.base)。
			//若 digits < 0，則會當作自尾端數起位數。
			//direct: directed rounding: undefined, 0, Infinity, -Infinity
			// https://en.wikipedia.org/wiki/Rounding
			//可視為 shift_digits() 之 frontend。
			function to_precision(digits, direct) {
				if ((digits = (digits < 0 ? 0 : this.length) - digits | 0)
					//長度相同: 毋須更動。
					&& digits !== this.length) {

					do_modified(this);

					var add_1;

					if (0 < digits) {
						var index = digits - 1, value, base = this[KEY_BASE];
						if (isNaN(direct)) {
							//nearest
							// http://mathworld.wolfram.com/NearestIntegerFunction.html
							if (base === (value = 2 * (this[index] || 0))) {
								for (--index; ;)
									if (--index < 0) {
										//四捨六入五成雙/best fraction
										//NOT 四捨五入
										add_1 = this[digits] % 2;
										break;
									} else if (0 < this[index]) {
										add_1 = true;
										break;
									}
							} else
								add_1 = base < value;

						} else if (!isFinite(direct)) {
							//floor, ceil
							//無條件捨去法/無條件進位法
							while (0 < --index)
								if (0 < this[index]) {
									add_1 = (0 < direct) ^ this[KEY_NEGATIVE];
									break;
								}
						}
						//else: treat as direct = 0, just truncate
					}

					shift_digits(this, digits);

					if (add_1 && base === ++this[0])
						//need to normalize
						normalize_digits(this);
				}

				return this;
			}

			//negative_exponent: 小數點後第 negative_exponent 位數(in this.base)，可為負數。
			//direct: directed rounding: undefined, 0, Infinity, -Infinity
			// https://en.wikipedia.org/wiki/Rounding
			function round(negative_exponent, direct) {
				if (0 < (negative_exponent = (negative_exponent | 0) + this[KEY_EXPONENT] + this.length))
					this.to_precision(negative_exponent, direct);
				return this;
			}


			// ---------------------------------------------------------------------//
			// advanced functions

			// WARNING 注意: this operation will modify both dividend and divisor!
			// return [ [ quotient Array ], remainder, Bézout coefficient for (dividend = this), Bézout coefficient for (divisor) ]
			// https://en.wikipedia.org/wiki/Extended_Euclidean_algorithm
			// https://en.wikipedia.org/wiki/Euclidean_algorithm
			// https://en.wikipedia.org/wiki/B%C3%A9zout%27s_identity
			function Euclidean_algorithm(divisor, get_coefficients) {
				var dividend = this, base = dividend[KEY_BASE],
				//
				quotient_Array = [], quotient, q, last_q,
				// coefficients
				// 前前group [dividend 應乘的倍數, divisor 應乘的倍數]
				c0 = [1, 0],
				// 前一group [dividend 應乘的倍數, divisor 應乘的倍數]
				c1 = [0, 1], c,
				// [dividend 採用 Integer, divisor 採用 Integer]
				is_i = [];

				function set_coefficient(i) {
					// 現 group = remainder = 前前group - quotient * 前一group
					if (!is_i[i]) {
						if (q && Number.isSafeInteger(c = c0[i] - c1[i] * last_q))
							return c;

						is_i[i] = true;
						c0[i] = new Integer(c0[i], base);
						c1[i] = new Integer(c1[i], base);
					}

					// TODO: 增進效率。
					return c0[i].add((new Integer(c1[i], base)).multiply(last_q), true);
				}

				do_modified(dividend);
				if (is_Integer(divisor))
					do_modified(divisor);
				else
					divisor = (new Integer(divisor, null, base)).abs();

				if ((KEY_TYPE in divisor) || divisor.compare(2) < 0)
					return [quotient_Array];

				for (; ;) {
					quotient = dividend.division(divisor);
					q = Number.isSafeInteger(last_q = quotient.valueOf(TYPE_TEST));
					if (!q)
						last_q = quotient;
					quotient_Array.push(last_q);
					if (dividend.is_0()) {
						q = [quotient_Array, Number.isSafeInteger(q = divisor.valueOf(TYPE_TEST)) ? q : divisor];
						if (get_coefficients)
							q.push(c1[0], c1[1]);
						return q;
					}

					if (get_coefficients)
						c = [set_coefficient(0), set_coefficient(1)],
						// shift
						c0 = c1, c1 = c;

					// swap (dividend, divisor)
					c = dividend;
					dividend = divisor;
					divisor = c;
				}
			}


			/*
			https://en.wikipedia.org/wiki/Square_(algebra)
			
			(please copy to a plain text)
			自乘時，乘法截圖: (下列數字皆為序號 index)
									5	4	3	2	1	0
								×	5	4	3	2	1	0
			-----------------------------------------------------------------------------------------------
									5×0	4×0	3×0	2×0	1×0	0×0
								5×1	4×1	3×1	2×1	1×1	1×0
							5×2	4×2	3×2	2×2	2×1	2×0
						5×3	4×3	3×3	3×2	3×1	3×0
					5×4	4×4	4×3	4×2	4×1	4×0
				5×5	5×4	5×3	5×2	5×1	5×0
			
			-----------------------------------------------------------------------------------------------
			注:加起來為序號 n 的組合:
				10	9	8	7	6	5	4	3	2	1	0
			
			** 除了自乘1倍外，皆為兩倍積。
			
			i:
				10	9	8	7	6	5	4	3	2	1	0
			i + 1 - this_length(6):
				5	4	3	2	1	0	1	-2	-3	-4	-5
			j start:
				5	4	3	2	1	0	0	0	0	0	0
			j end:
				5	4	4	3	3	2	2	1	1	0	0
			
			*/
			function square() {
				if ((KEY_TYPE in this) || this.is_0() || this.is_0(1))
					// 不處理虛數與複數。
					// do simulation: 模擬與 NaN 等極端數字作運算。
					return this;

				// 至此特殊值處理完畢。

				do_modified(this);
				delete this[KEY_NEGATIVE];
				this[KEY_EXPONENT] *= 2;

				var i = 0, j, this_length = this.length, length = 2 * this_length, product, value,
				//初始化。
				result = new Array(length--).fill(0);

				for (; i < length ; i++)
					for (j = Math.max(0, i + 1 - this_length) ; 2 * j <= i; j++)
						if (product = this[j] * this[i - j]) {
							if (2 * j < i)
								product *= 2;
							if (Number.isSafeInteger(value = result[i] + product))
								result[i] = value;
							else
								//手動進位。
								result[i + 1]++, result[i] -= Number.MAX_SAFE_INTEGER - product;
						}

				//將 {Array}result → this，順便作正規化。
				for_each_digit.call(result, normalize_handle, this);

				return this;
			}

			//9741
			//var square_root_base = Math.floor(Math.sqrt(Math.sqrt(MAX_SAFE_INTEGER)));
			//for debug
			//square_root_base = 1000;
			/*
			https://en.wikipedia.org/wiki/Square_root
			https://en.wikipedia.org/wiki/Methods_of_computing_square_roots
			
			
			slow method (don't use this):
			(please copy to a plain text)
			精準/準確直式開方 以  BASE = 100^2 = 10000 為例，sqrt(294565622121) = 542739：
			accumulate        54   27   39  remainder
			 54             2945 6562 2121
			+54             2916              ① q=Math.sqrt(2945)|0 = 54, 54×54 = 2916
			10827             29 6562         ② remainder=296562, accumulate=10800, q=remainder/accumulate|0 = 27, 自 q 起找尋 (accumulate+q)×q <= remainder 之最大數 q (if(remainder-accumulate*q<q*q)q--;)，即為 27。
			+  27             29 2329         ③ 10827×27 = 292329
			1085439              4233 2121    ④ remainder=42332121, accumulate=1085400, q=remainder/accumulate|0 = 39, 自 q 起找尋 (accumulate+q)×q <= remainder 之最大數 q (if(remainder-accumulate*q<q*q)q--;)，即為 39。
				 39              4233 2121    ⑤ 1085439×39 = 42332121
										 0    ⑥ remainder=0, done.
			*/
			//{Undefined|natural number}digit
			// WARNING 注意: this will get floor(sqrt(this))，結果僅會回傳整數！
			function square_root(negative_exponent) {
				if (this[KEY_NEGATIVE] || (KEY_TYPE in this) || this.is_0() || this.is_0(1))
					// 不處理虛數與複數。
					// do simulation: 模擬與 NaN 等極端數字作運算。
					return this.assignment(Math.sqrt(this.valueOf(TYPE_TEST)));

				// 至此特殊值處理完畢。

				if (0 < (negative_exponent |= 0) && Number.isSafeInteger(negative_exponent))
					shift_digits(this, -negative_exponent * 2 - this[KEY_EXPONENT]);

				// assert: this.at(-1) > 0
				var index = this.length, index_sr = --index / 2 | 0, base = this[KEY_BASE];
				if (!index_sr)
					// assert: this.length <= 2
					return this.assignment(Math.floor(Math.sqrt((this[1] || 0) * base + (this[0] || 0))));


				/*
				use Newton's method: x1 = (x0 + number / x0) / 2
				即使兩數僅差 1，亦不可直接回傳，有可能為 (準確值+1) & (準確值+2) 之類的。
			
				initial   sqrt  取值迭代變化: sr → _sr
				n^2 - 1   n-1   n+1 → n   → n-1 → n  ** NG: 反轉了。
				n^2       n     n+1 → n   → n   → n
				n^2       n     n-1 → n+  → n   → n
				n^2 + 1   n     n+2 → n   → n   → n
				n^2 + 1   n     n-1 → n+  → n   → n
			
				故:
				1. 取 initial value >= sqrt
				2. 當 _sr - sr = 0 or 1, 反轉時取較小的 sr 即為可回傳 sqrt。
			
				*/

				//決定 determines the initial value。
				//sr: square root value
				// TODO: 取更多位數。
				var sr, _sr = this[index--];
				if (index % 2 === 0)
					//e.g., √1024 = 32
					//取2位數
					_sr = _sr * base + this[index];
				else
					//e.g., √10000 = 100
					//取3位數
					_sr += (this[index] + this[index - 1] / base) / base;
				_sr = Math.sqrt(_sr);

				sr = new Integer(0, base);
				sr[KEY_EXPONENT] = -negative_exponent;

				//初始化 the initial value。
				sr[index_sr] = _sr | 0;
				//+1: 保證 initial value >= sqrt(this)
				sr[--index_sr] = ((_sr % 1) * base | 0) + 1;
				//sr[0] 已被設定過。
				while (0 < index_sr)
					sr[--index_sr] = 0;

				for (base--; ; sr = _sr) {
					//use Newton's method: x1 = (number / x0 + x0) / 2
					//_sr: next sr
					_sr = this.clone().division(sr).add(sr).division(2);

					/*
					check if 反轉: _sr - sr = 1
					possible condition:
					part:       1            2      3
					_sr = (the same digits)  n    (00000)
					 sr = (the same digits) (n-1) (99999)
			
					part 1, 3 may not exist, the part 2 is the keypoint.
			
					e.g.,
					 sr =  9999   19999   32999  42342
					_sr = 10000   20000   33000  42343
					*/

					for (index_sr = 0; index_sr < _sr.length;)
						if (_sr[index_sr] === 0 && sr[index_sr] === base)
							//skip part 3.
							index_sr++;
						else {
							// check part 2.
							index = _sr[index_sr] - (sr[index_sr] || 0);
							if (index_sr === 0 && index === 0 || index === 1)
								//skip part 1.
								for (; ;)
									if (++index_sr === _sr.length)
										// assert: _sr - sr = 0 or 1
										return this.assignment(sr);
									else if (sr[index_sr] !== _sr[index_sr])
										break;
							break;
						}
				}
			}

			// https://en.wikipedia.org/wiki/Nth_root
			// https://en.wikipedia.org/wiki/Nth_root_algorithm
			//nth root (surds): degree √radicand =	root
			function root(degree, negative_exponent) {
				if (!Number.isSafeInteger(degree) || degree < 3) {
					if (degree === 0)
						return this.assignment(1);
					if (degree === 2)
						//square_root() is faster
						return this.square_root(negative_exponent);
					if (degree !== 1)
						library_namespace.error('root: Invalid degree: [' + degree + '].');
					return this;
				}

				if (this[KEY_NEGATIVE])
					// 不處理虛數與複數。
					return this.assignment(NaN);
				if (KEY_TYPE in this)
					return this[KEY_TYPE];

				// 至此特殊值處理完畢。
				do_modified(this);

				if (0 < (negative_exponent |= 0) && Number.isSafeInteger(negative_exponent))
					shift_digits(this, -negative_exponent * 2 - this[KEY_EXPONENT]);

				// assert: this.at(-1) > 0
				var index = this.length, index_sr = --index / 2 | 0, base = this[KEY_BASE];
				if (!index_sr)
					// assert: this.length <= 2
					return this.assignment(Math.floor(Math.sqrt((this[1] || 0) * base + (this[0] || 0))));

				TODO;

				var r, delta;

				//+1: 保證 initial value >= root(this)

				for (; ;) {
					//use Newton's method
					delta = this.clone().division(r.clone().power(degree - 1)).add(r, true).division(2);
					if (delta.compare(0) >= 0)
						return this.assignment(r);
					r.add(delta.derive(degree));
				}
			}


			// ---------------------------------------------------------------------//

			// return {Number} = antecedent(=this) : consequent = N / D
			function ratio_to(consequent) {
				if (!consequent)
					// do simulation: 模擬與 NaN 等極端數字作運算。
					return (this[KEY_NEGATIVE] ? -1 : 1) / 0;
				if (typeof consequent === 'number')
					return this.valueOf() / consequent;

				// 至此特殊值處理完畢。
				//以下操作目的:當 this, consequent 個別過大或過小，但比例可表示時，嘗試表現之。

				var base = this[KEY_BASE], n = this.valueOf(TYPE_info_for_large), exponent_base = 0, next_n;
				if (Array.isArray(n))
					exponent_base = n[1], n = n[0];

				if (Array.isArray(consequent = (new Integer(consequent, null, base)).valueOf(TYPE_info_for_large)))
					exponent_base -= consequent[1], consequent = consequent[0];

				exponent_base = Math.pow(base, exponent_base);
				next_n = n / consequent;
				if (next_n === 0 || !isFinite(next_n))
					n = n * exponent_base / consequent;
				else
					n = next_n * exponent_base;

				return n;
			}


			//max_digits[base]={integer}, min_digits[base]={integer}
			var max_digits = Object.create(null), min_digits = Object.create(null),
			//
			LOG_MAX = Math.log(Number.MAX_VALUE), LOG_MIN = Math.log(Number.EPSILON);
			function max_digits_of(base) {
				if (!(base in max_digits))
					max_digits[base] = (LOG_MAX / Math.log(base) | 0) + 1;
				return max_digits[base];
			}
			function min_digits_of(base) {
				if (!(base in min_digits))
					min_digits[base] = LOG_MIN / Math.log(base) | 0;
				return min_digits[base];
			}


			// 當數字過大，轉回傳 {String}
			var TYPE_String_for_large = 1,
			// return [value, exponent]: this = value * base ^ exponent，value 已為可計算之極端值（最大或最小）
			TYPE_info_for_large = 2,
			// 與 NaN 等極端數字作運算用。僅回傳 NaN, ±Infinity, ±1, 0, ±是否在  Number.isSafeInteger() 內。
			TYPE_TEST = 3;
			// WARNING 注意: 若回傳非 Number.isSafeInteger()，則會有誤差，不能等於最佳近似值。
			function valueOf(type) {
				var value;
				//由消費最少，且必須先檢測的開始檢測。
				if (KEY_TYPE in this) {
					value = this[KEY_TYPE];
					return this[KEY_NEGATIVE] ? -value : value;
				}

				var v, base = this[KEY_BASE], exponent = this[KEY_EXPONENT],
				//實際應為首個 nonzero 之位置。
				index = this.length, e0, next_value, base_now = ZERO_EXPONENT;

				//先檢測是否為 {Number} 可表示之範圍。
				if (!type && (value = index + exponent) <= min_digits_of(base))
					value = 0;
				else if (!type && max_digits_of(base) < value)
					value = Infinity;


				else if (type === TYPE_TEST && this.length < 2) {
					if ((value = this[0] || 0) && exponent)
						value *= Math.pow(base, exponent);

				} else {
					// 這邊將處理3種情況:
					// F: first digit 首位.
					// e0: digit of base^0.
					// L: last digit that can presented.
					// F---L---e0 : 直接在過程 phase 1 即解決掉。
					// F---L=e0   : 直接在過程 phase 1 即解決掉。
					// F---e0--L  : phase 1 + 2。
					// F=e0----L  : phase 1 + 2。
					// e0--F---L  : 在過程 phase 2 解決掉。
					//分為整數與小數兩階段處理，是為了盡可能保持精度。

					//至此，除非是 TYPE_info_for_large，否則就算最後值應為 Infinity 或是 0，也應該會作到最後一個 loop 才發現。

					// phase 1: 整數
					for (value = 0, e0 = Math.max(0, -exponent) ; e0 < index; value = next_value)
						if ((next_value = (v = value * base) + (this[--index] || 0)) === Infinity
							//已經無法造成影響。
							|| this[index] && next_value === v) {
							//+1: 因為這邊取用 value，而非 next_value。
							index += exponent + 1;
							if (this[index])
								//彌補差值。
								value += this[index] / base;
							if (type === TYPE_info_for_large)
								return [this[KEY_NEGATIVE] ? -value : value, index];
							else if (type === TYPE_String_for_large) {
								//轉成 log_10(this)
								value = Math.log10(value) + Math.log10(base) * index;
								value = Math.pow(10, value % 1) + 'e+' + (value | 0);
							} else if (type !== TYPE_TEST) {
								// normal: 強迫回傳 {Number}
								value = next_value;
								index--;
								if (value !== Infinity && index)
									value *= Math.pow(base, index);
							}
							//TYPE_TEST: 與 NaN 等極端數字相較，再大的 Integer 都只是小兒科。因為不在乎精度，無須再處理。
							//但須注意 assignment() 之使用。

							//不需再處理小數了。
							index = 0;
							break;
						}

					// phase 2: 小數
					if (0 < index) {
						// 在 [length=12].exponent=-10 之類的情況下保持精度。
						for (; 0 < index;) {
							base_now /= base;
							if (this[--index]) {
								next_value = value + this[index] * base_now;
								if (next_value === value)
									//已經無法造成影響。
									break;
								if (0 === base_now / base) {
									value += this[index] / base * base_now;
									break;
								}
								value = next_value;
							}
						}
						//基本上，上面算法假設 index 在 E0 之前。因此需要對 index 在 E0 之後，即首位已在 E0 之後的情況作修正。
						if (this.length + exponent < 0) {
							if (type === TYPE_info_for_large)
								return [this[KEY_NEGATIVE] ? -value : value, this.length + exponent];
							next_value = value * Math.pow(base, index + exponent);
							if (next_value === 0) {
								//轉成 log_10(this)
								value = Math.log10(value) + Math.log10(base) * (this.length + exponent);
								value = value + 'e+' + (value | 0);
							} else
								value = next_value;
						}
					}
				}
				// minus sign
				return this[KEY_NEGATIVE] ? typeof value === 'number' ? -value : '-' + value : value;
			}

			function toString(radix) {
				var base;
				if (radix && isNaN(radix))
					radix = (base = Array.isArray(radix) ? radix : String(radix).split('')).length;
				else if (!valid_radix(radix))
					radix = DEFAULT_RADIX;
				if (!base && this[KEY_CACHE] && this[KEY_CACHE][radix])
					return this[KEY_CACHE][radix];

				var digits, value, zero;
				if (KEY_TYPE in this)
					digits = [this[KEY_TYPE]];
				else {
					if (!base)
						base = DEFAULT_DIGITS;
					if (typeof base === 'string')
						// IE8 不能用 string[index]。'ab'[1] === undefined, 'ab'[1] !== 'b'。
						// base.chars()
						base = base.split('');
					// assert: Array.isArray(base)
					zero = base[0];
					digits = [];
					value = new Integer(this, radix, true);
					value.forEach(function (digit) {
						digits.push(base[digit]);
					});
					if (value = value[KEY_EXPONENT])
						if (0 < value)
							digits.unshift(zero.repeat(value));
						else {
							if (digits.length < (value = -value))
								// 補足長度。
								if (digits.fill) {
									// Array.prototype.fill() 只會作用於 0~原先的 length 範圍內！
									var i = digits.length;
									digits.length = value;
									digits.fill(zero, i);
								} else
									for (var i = digits.length; i < value;)
										digits[i++] = zero;
							// add 小數點
							digits.splice(value, 0, radix_point);
							while (digits[0] == zero)
								// 去除末端的 '0'。
								digits.shift();
							if (digits[0] === radix_point)
								digits.shift();
						}
				}

				// 去除前導的 '0'。
				if (value = digits.length)
					while (0 < --value && digits[value] === zero)
						digits.pop();
				else
					digits = [zero];

				if (digits.at(-1) === radix_point)
					digits.push(zero);
				if (this[KEY_NEGATIVE])
					// minus sign
					digits.push('-');

				digits.reverse();

				if (!Array.isArray(this[KEY_CACHE]))
					this[KEY_CACHE] = [];
				return this[KEY_CACHE][radix] = digits.join('');
			}

			// assert: {ℕ⁰:Natural+0}this
			// TODO: 處理小數/負數
			function digits(radix) {
				if (!valid_radix(radix))
					radix = DEFAULT_RADIX;
				var count = count_exponent(this[KEY_BASE], radix);
				if (!(count > 0))
					return this.toString(radix).split('').map(function(digit) {
						return parseInt(digit, radix);
					});

				var digits = [];
				this.forEach(function(value) {
					for (var index = 0; index < count; index++) {
						digits.unshift(value % radix);
						value = value / radix | 0;
					}
				});
				while (!digits[0])
					digits.shift();
				return digits;
			}

			function digit_sum(radix) {
				return this.digits(radix).sum();
			}

			// ---------------------------------------------------------------------//
			//初等數論函數/數學常數
			// https://zh.wikipedia.org/wiki/%E6%95%B0%E5%AD%A6%E5%B8%B8%E6%95%B0

			// return this ^ {Integer}exponent % {Integer}modulus
			function power_modulo(exponent, modulus) {
				if ((KEY_TYPE in this) || this[KEY_EXPONENT] < 0
					//得允許 {Integer}exponent。
					//|| !Number.isSafeInteger(exponent) || exponent < 0
					)
					return;

				exponent = new Integer(exponent, null, 2, true);
				exponent[KEY_EXPONENT] && exponent.expand_exponent();
				if ((KEY_TYPE in exponent) || exponent[KEY_EXPONENT] || exponent[KEY_NEGATIVE])
					return;

				modulus = new Integer(modulus, null, this[KEY_BASE]);

				var remainder = new Integer(ZERO_EXPONENT, this[KEY_BASE]), power = this.clone().abs();

				for (power.division(modulus) ; ;) {
					if (exponent[0] === 1)
						remainder.multiply(power).division(modulus);
					if (exponent.length === 1)
						return remainder;
					power.square().division(modulus);
					if (power.is_0(1))
						return remainder;
					shift_digits(exponent, 1, true);
				}
			}

			//	Miller–Rabin primality test
			//	return true: is composite, undefined: probable prime (PRP) / invalid number
			// https://en.wikipedia.org/wiki/Miller%E2%80%93Rabin_primality_test
			function Miller_Rabin(times) {
				if ((KEY_TYPE in this) || this[KEY_EXPONENT] < 0
					//得允許 {Integer}exponent。
					//|| !Number.isSafeInteger(exponent) || exponent < 0
					)
					return;

				// assert: (this) is integer, (this) % 2 = 1, (this) > 4
				var n_1 = (new Integer(this, DECIMAL_BASE)).add(-1), d = n_1.clone(), s = 0, a, x;
				while (d[0] % 2 === 0)
					s++, d = d.division(2);
				// assert: s > 0

				if (!(times |= 0))
					times = 2;

				for (var prime_index = 0; prime_index < times;) {
					// 3rd 起應該用大數( > 307) 偵測。
					a = new Integer(get_prime(++prime_index + (prime_index < 3 ? 0 : 60)));
					x = a.power_modulo(d, this);
					if (x.is_0(1) || x.compare_amount(n_1) === 0)
						continue;

					var i = 1, j = 1;
					for (; i < s; i++) {
						x.square().division(this);
						if (x.is_0(1))
							return true;
						if (x.compare_amount(n_1) === 0) {
							j = 0;
							break;
						}
					}
					if (j)
						// composite
						return true;
				}

				// probable prime to base 2, 3.

				// probable prime (PRP), probably prime
				// https://en.wikipedia.org/wiki/Probable_prime
			}

			var get_prime = library_namespace.data.math.prime,
				math_not_prime = library_namespace.data.math.not_prime,
				math_factorize = library_namespace.data.math.factorize,
			// copy from data.math
			sqrt_max_integer = Math.sqrt(Number.MAX_SAFE_INTEGER) | 0;
			// return false: number: min factor, is prime, true: not prime, undefined: maybe prime (unknown)
			// ** modified from data.math.not_prime()
			function not_prime(limit) {
				var integer = this.valueOf();
				if (Number.isSafeInteger(integer) && !(sqrt_max_integer < integer))
					return math_not_prime(integer);

				if ((KEY_TYPE in this) || this[KEY_EXPONENT] < 0)
					return;

				// 可先檢測此數是否在質數列表中。

				if (!limit)
					//迫於未能使用好的演算法，只好限制使用時間。
					limit = 1e5;

				// 採用試除法, trial division 檢測小質數整除性。
				var prime, index = 1;
				while (prime = get_prime(index++, limit))
					if (this.clone().modulo(prime).is_0())
						return this.compare_amount(prime) !== 0 && prime;

				library_namespace.debug('not_prime: 由於所測試的質數 '
					+ prime + ' 已大於 limit ' + limit
					+ '，因此不再試除 [' + this.toString() + ']。', 3);

				return this.Miller_Rabin();

				// TODO: https://en.wikipedia.org/wiki/Baillie%E2%80%93PSW_primality_test
				// TODO: https://en.wikipedia.org/wiki/Lucas_pseudoprime
			}


			// Pollard's rho algorithm is a general-purpose integer factorization algorithm.
			// https://en.wikipedia.org/wiki/Pollard's_rho_algorithm

			// The first rho method used random walks to find factors
			// https://sites.google.com/site/jmptidcott2/nthy
			function Pollards_rho_1975() {
				for (var x = new Integer(2), y = x.clone(), d; ;) {
					// f(x) = (x^2 + 1) % N
					x.square().add(1).division(this);
					y.square().add(1).division(this);
					y.square().add(1).division(this);
					//when n is a prime number, d will be always 1.
					d = Integer_GCD(y.clone().add(x, true).abs(), this.clone());
					if (d !== 1)
						return this.compare_amount(d) !== 0 && d;
				}
			}

			// http://maths-people.anu.edu.au/~brent/pub/pub051.html
			// https://github.com/search?q=Pollard+rho+Brent+factor&type=Code
			// http://comeoncodeon.wordpress.com/2010/09/18/pollard-rho-brent-integer-factorization/
			// WARNING: 雖然此演算法或可得到因子，但對於過大因子，將耗費大量時間！例如為十位數以上之質數時，恐得使用五分鐘以分解！
			// WARNING: Note that this algorithm may not find the factors and will return failure for composite n. In that case, use a different f(x) and try again.
			function Pollards_rho_1980() {
				if ((KEY_TYPE in this) || this[KEY_EXPONENT] < 0)
					// Invalid integer to factorize
					return;
				if (this.clone().modulo(2) === 0 || this.clone().modulo(3) === 0)
					return false;

				// reset initial value
				// assert: this > max(y, m, c)
				var y = new Integer(get_prime(2 + Math.random() * 1e3 | 0)),
					m = get_prime(2 + Math.random() * 1e3 | 0),
					c = get_prime(2 + Math.random() * 1e3 | 0),
					r = 1, q = new Integer(1), x, i, k, ys, G;
				do {
					for (x = y.clone(), i = r; i--;)
						// f(x) = (x^2 + c) % N
						y.square().add(c).division(this);
					k = 0;
					do {
						for (ys = y, i = Math.min(m, r - k) ; i-- ;) {
							// f(x) = (x^2 + c) % N
							y.square().add(c).division(this);
							q.multiply(x.clone().add(y, true).abs()).division(this);
						}
						G = Integer_GCD(q.clone(), this.clone());
						k += m;
					} while (k < r && G === 1);
					r *= 2;
					// TODO: 當 r 過大，例如為十位數以上之質數時，過於消耗時間。
				} while (G === 1);

				if (this.compare_amount(G) === 0)
					do {
						// f(x) = (x^2 + c) % N
						ys.square().add(c).division(this);
						G = Integer_GCD(x.clone().add(ys, true).abs(), this.clone());
					} while (G === 1);

				return this.compare_amount(G) !== 0 && G;
			}


			// TODO: the elliptic curve method (ECM)

			/**
			 * 取得某數的質因數分解，整數分解/因式分解/素因子分解, prime factorization, get floor factor.<br />
			 * 唯一分解定理(The Unique Factorization Theorem)告訴我們素因子分解是唯一的，這即是稱為算術基本定理 (The
			 * Fundamental Theorem of Arithmeric) 的數學金科玉律。
			 * 
			 * ** modified from data.math.factorize()
			 * 
			 * @param {Number}radix
			 *            output radix
			 * @param {Number}limit
			 *            maximum prime to test
			 * 
			 * @return {Object}factor {prime1:power1, prime2:power2, ..}
			 * 
			 * @see <a href="http://homepage2.nifty.com/m_kamada/math/10001.htm"
			 *      accessdate="2010/3/11 18:7">Factorizations of 100...001</a>
			 *      https://en.wikipedia.org/wiki/Integer_factorization
			 */
			function factorize(radix, limit) {
				var integer = this.valueOf();
				if (Number.isSafeInteger(integer))
					return math_factorize(integer, radix);

				if ((KEY_TYPE in this) || this[KEY_EXPONENT] < 0) {
					library_namespace.error('factorize: Invalid integer: [' + this.toString() + '].');
					return;
				}

				if (!limit)
					//迫於未能使用好的演算法，只好限制使用時間。
					limit = 1e6;

				if (!valid_radix(radix))
					// IE8 中，無法使用 Number.toString(undefined)。
					//radix = undefined;
					radix = DEFAULT_RADIX
				integer = this.clone();
				delete integer[KEY_NEGATIVE];

				var prime, index = 1, factors = Object.create(null), power,
				get_sqrt = function () {
					sqrt = Math.floor(integer.clone().square_root().valueOf());
				}, sqrt = get_sqrt();
				Object.defineProperty(factors, 'toString', {
					enumerable: false,
					value: math_factorize._toString
				});

				for (; ;) {
					// 採用試除法, trial division。
					if (integer.clone().modulo(prime = get_prime(index++)).is_0()) {
						for (power = 1; (integer = integer.division(prime)).clone().modulo(prime).is_0() ;)
							power++;
						factors[prime.toString(radix)] = power;
						if (integer.is_0(ZERO_EXPONENT))
							return factors;
						if (Number.isSafeInteger(sqrt = integer.valueOf())) {
							//use data.math.factorize();
							sqrt = math_factorize(sqrt, radix, index);
							for (prime in sqrt)
								factors[prime] = sqrt[prime];
							return factors;
						}
						get_sqrt();
					}

					if (sqrt < prime) {
						// assert: integer is now prime.
						factors[integer.toString(radix)] = 1;
						return factors;
					}

					if (limit < prime) {
						if (false) {
							if (integer.Miller_Rabin())
								library_namespace.warn('factorize: 由於所測試的質數 ' + prime + ' 已大於 limit ' + limit
									+ '，因此不再試除餘下之合數因子 [' + integer.toString() + ']；您有必要自行質因數分解此數！');
							factors[integer.toString(radix)] = 1;
						}

						prime = [];
						power = function (i) {
							if (i.not_prime()) {
								var p, count = 3;
								while (count-- && !(p = i.Pollards_rho()));
								if (p) {
									power(p = Integer(p));
									power(i.clone().division(p));
									return;
								} else
									library_namespace.warn('factorize: 無法分解'
										+ (library_namespace.is_debug() && i.Miller_Rabin() ? '合數' : '') + '因子 [' + i.toString() + ']；您或許有必要自行質因數分解此數！');
							}
							prime.push(i);
						};
						power(integer);

						prime.sort(Integer_compare);
						prime.forEach(function (p) {
							p = p.toString(radix);
							if (p in factors)
								factors[p]++;
							else
								factors[p] = 1;
						});

						return factors;
					}
				}
			}


			var summation_cache = {
				// cache of mathematical constant ℯ
				E: new Integer(Math.E.toString(), DEFAULT_RADIX, DEFAULT_RADIX),
				// cache of mathematical constant ln 2
				LN2: new Integer(Math.LN2.toString(), DEFAULT_RADIX, DEFAULT_RADIX),
				// cache of mathematical constant ln 10
				LN10: new Integer(Math.LN10.toString(), DEFAULT_RADIX, DEFAULT_RADIX),
				// cache of mathematical constant π
				PI: new Integer(Math.PI.toString(), DEFAULT_RADIX, DEFAULT_RADIX)
			};
			//@inner
			// https://en.wikipedia.org/wiki/Summation#Capital-sigma_notation
			function summation(name, operation, precision, initial_value, error_digits) {
				if (Number.isSafeInteger(precision |= 0) && (!name || summation_cache[name].length < precision)) {
					var sum = new Integer(isNaN(initial_value) ? 1 : initial_value);
					if (!error_digits)
						error_digits = 1;
					//欲取的位數。
					shift_digits(sum, -Math.ceil(precision / DECIMAL_BASE_LENGTH) - error_digits);

					// operation(sum): main loop of summation
					sum = new Integer((operation(sum) || sum).to_precision(-error_digits), DEFAULT_RADIX);

					if (name)
						summation_cache[name] = sum;
					name = sum;

				} else
					name = summation_cache[name];

				return name.clone().to_precision(precision);
			}

			//自然對數函數的底數
			// https://en.wikipedia.org/wiki/E_(mathematical_constant)
			// calculate mathematical constant ℯ ≈
			// TODO: 誤差範圍評估/估計
			// https://en.wikipedia.org/wiki/Errors_and_residuals_in_statistics
			function Integer_E(precision) {
				return summation('E', function (E) {
					for (var index = 0, addend = E.clone() ;
						!(addend = addend.division(++index)).is_0() ;)
						E.add(addend);
				}, precision);
			}


			//return ℯ^exponent
			//Integer_exp({Number}real number exponent, precision)
			// https://en.wikipedia.org/wiki/Exponential_function
			function Integer_exp(exponent, precision) {
				var l, error_digits = 2,
				//
				integer_part = is_Integer(exponent) && exponent[KEY_BASE] === DEFAULT_BASE;
				if (!integer_part)
					exponent = new Integer(exponent, null, DEFAULT_BASE);

				if ((KEY_TYPE in exponent) || exponent.is_0())
					// 不處理虛數與複數。
					// do simulation: 模擬與 NaN 等極端數字作運算。
					return Math.exp(exponent.valueOf(TYPE_TEST));

				if (exponent[KEY_NEGATIVE]) {
					// negative exponent.
					delete exponent[KEY_NEGATIVE];
					shift_digits(l = new Integer(1), -precision - error_digits);
					return l.division(Integer_exp(exponent, precision + error_digits)).to_precision(precision);
				}

				if (exponent.is_0(1))
					return Integer_E(precision);


				// 至此特殊值處理完畢。

				if (exponent[KEY_EXPONENT] < 0)
					if (0 < exponent.length + exponent[KEY_EXPONENT] && 9 < (l = exponent.valueOf())) {
						//分成兩部分處理以加快速度: exp(40.3) = exp(40) * exp(.3)。
						if (integer_part)
							exponent = exponent.clone();
						return Integer_exp(integer_part = l | 0, precision + error_digits)
							//fractional part 分數/小數部分
							.multiply(Integer_exp(exponent.add(-integer_part), precision + error_digits))
							.to_precision(precision);

					} else if (0 < (l = exponent.length - Math.ceil(precision / DECIMAL_BASE_LENGTH) - error_digits)) {
						//過精細的 exponent 無用。
						if (integer_part)
							exponent = exponent.clone();
						shift_digits(exponent, l);
					}

				return summation(null, function (exp) {
					//1 - exp[KEY_EXPONENT] for precision
					for (var index = 0, addend = exp.clone(), digits = error_digits - exp[KEY_EXPONENT];
						//截斷 addend 以加速運算。
						digits < addend.length && shift_digits(addend, addend.length - digits),
						!(addend = addend.multiply(exponent).division(++index)).is_0()
						//當數值過小，即使非 0 亦無意義。
						&& exp[KEY_EXPONENT] < addend.length + addend[KEY_EXPONENT];)
						digits < exp.add(addend).length && shift_digits(exp, exp.length - digits);
				}, precision, undefined, error_digits);
			}


			// https://en.wikipedia.org/wiki/Natural_logarithm_of_2#Series_representations
			// https://en.wikipedia.org/wiki/Logarithm#Power_series
			function Integer_LN2(precision) {
				return summation('LN2', function (LN2) {
					// TODO: no clone
					var index = 1, d = LN2.clone(), addend;
					while (!(addend = (d = d.division(9)).clone().division(index += 2)).is_0())
						LN2.add(addend);
					return LN2.division(3);
				}, precision, 2, 1);
			}

			// https://en.wikipedia.org/wiki/Logarithm#Power_series
			function Integer_LN10(precision) {
				return summation('LN10', function (LN10) {
					for (var index = 1, d = LN10.clone(), addend;
						!(addend = (d = d.division(81)).clone().division(index += 2)).is_0() ;)
						LN10.add(addend);
					return LN10.division(9).add(Integer_LN2(precision + 1).multiply(3));
				}, precision, 2);
			}

			//@inner
			// https://en.wikipedia.org/wiki/Natural_logarithm
			// https://en.wikipedia.org/wiki/Logarithm#Power_series
			// ln({Integer}power, precision)
			function ln(power, precision) {
				var error_digits = 1, exponent = Math.ceil((precision |= 0) / DECIMAL_BASE_LENGTH) + error_digits,
				//
				ln_value = new Integer(2), index, addend, b, d, to_add;

				power = new Integer(power, null, DECIMAL_BASE);

				//正規化:去除末尾的0。
				for (index = 0; index < power.length; index++)
					if (power[index]) {
						if (index)
							shift_digits(power, index);
						break;
					}

				for (d = 0, index = power[0], addend = 10; index % addend === 0;)
					d++, to_add = addend, addend *= 10;
				if (d)
					power = power.division(to_add);
				//至此處理完 10 ^ d 的部分。

				for (b = 0, index = power[0], addend = 2; index % addend === 0;)
					b++, to_add = addend, addend *= 2;
				if (b)
					power = power.division(to_add);
				//let 1 <= power < 2 以加速 main loop 運算。
				//先使 power 首位 [power.length - 1] < 2。
				while (power.at(-1) > 1) {
					if (power[0] % 2 === 1)
						//預防失去精度。
						shift_digits(power, -1);
					b++, power = power.division(2);
				}
				// assert: 1 <= power.at(-1)

				//至此處理完 2 ^ b 的部分。

				//再使 power 首位 power.at(-1) 之 exponent 為 0。
				if (to_add = (index = power.length - 1) + power[KEY_EXPONENT]) {
					d += to_add * DECIMAL_BASE_LENGTH;
					power[KEY_EXPONENT] = -index;
				}
				// assert: 1 <= power < 2,  power.at(-1) === ZERO_EXPONENT === 1

				if (d)
					d = Integer_LN10(precision + error_digits * DECIMAL_BASE_LENGTH).multiply(d);
				if (b) {
					to_add = Integer_LN2(precision + error_digits * DECIMAL_BASE_LENGTH).multiply(b);
					if (d)
						to_add.add(d);
				} else
					to_add = d || 0;

				if (!index)
					return to_add ? to_add.to_precision(-error_digits * DECIMAL_BASE_LENGTH) : new Integer(0, DEFAULT_RADIX);

				// assert: 1 < power < 2,  power.at(-1) === ZERO_EXPONENT === 1


				d = power.clone();
				d[index = d.length - 1] = 2;
				b = power.clone();
				if (Array.isArray(b))
					b.pop();
				else
					b[index] = 0;
				// assert: now: d = power + 1, b = power - 1

				//d = ( (power + 1) / (power - 1) ) ^ 2
				d = d.division(b, exponent).square().to_precision(exponent);

				//簡化d，去掉末尾的 0。
				index = 0;
				while (index < d.length && !d[index])
					index++;
				if (index)
					shift_digits(d, index);

				//初始化 ln_value, b, ..
				shift_digits(ln_value, -exponent);
				b = ln_value.clone();
				index = 1;

				// main loop of summation
				while (!(addend = (b = b.division(d, exponent)).clone().division(index += 2)).is_0())
					ln_value.add(addend);

				d = power.clone();
				d[index = d.length - 1] = 2;
				// assert: now: d = power + 1

				if (Array.isArray(power))
					power.pop();
				else
					power[index] = 0;

				ln_value = new Integer(ln_value.multiply(power).division(d), DEFAULT_RADIX);

				if (to_add)
					ln_value.add(to_add);

				return ln_value.to_precision(precision);
			}

			//Logarithm: log _ base(power) = exponent
			// https://en.wikipedia.org/wiki/Logarithm
			//default base: e
			//this.log({Number}real number base, precision)
			//return {Number|Integer}
			function log(base, precision) {
				if (this[KEY_NEGATIVE] || (KEY_TYPE in this) || this.is_0() || this.is_0(1) || base && !isFinite(+base))
					// 不處理虛數與複數。
					// do simulation: 模擬與 NaN 等極端數字作運算。
					return Math.log(this.valueOf(TYPE_TEST)) / (base ? Math.log(+base) : 1);

				// 至此特殊值處理完畢。

				var base_exponent = 0, value = this, remainder, quotient;
				if (base) {
					base = new Integer(quotient = base, null, this[KEY_BASE]);
					if (base[KEY_TYPE] || !(base.compare(ZERO_EXPONENT) > 0)) {
						library_namespace.error('log: Invalid base: [' + quotient + '].');
						return NaN;
					}

					// 盡量取得整數次方。
					for (; ; base_exponent++, value = quotient) {
						remainder = value.clone();
						quotient = remainder.division(base);
						if (!remainder.is_0())
							break;
					}

					// assert: is_Integer(base)
					// assert: this = value * base ^ {0|natural number}base_exponent in base
					// assert: value === value % base > 0
				}

				if (precision |= 0) {
					//+ 1: error digits
					value = ln(value, precision + (base ? 1 : 0));
					if (base) {
						if (!value.is_0())
							value = value.division(ln(base, precision + 1));
						if (base_exponent)
							value.add(base_exponent);
					}
					return value.to_precision(precision);
				}


				//將 value 轉成可表現之最大精度 {Number}。
				value = value.valueOf(TYPE_info_for_large);

				value = typeof value === 'number' ? Math.log(Math.abs(value))
					// assert: value = [{Number}large value, {0|natural number}exponent in this[KEY_BASE]]
					: value[1] * Math.log(this[KEY_BASE]) + Math.log(Math.abs(value[0]));

				if (base) {
					if (value)
						value /= base.log();
					value += base_exponent;
				}

				return value;
			}


			// Exponentiation 冪/乘方: base ^ exponent = power
			// https://en.wikipedia.org/wiki/Exponentiation
			// https://en.wikipedia.org/wiki/Exponentiation_by_squaring
			// {natural number}exponent
			// {natural number}modulus = base^this.exponent
			// this.power({Number}real number exponent, precision)
			function power(exponent, precision) {
				exponent = Integer(exponent);
				if (exponent.is_0(1))
					return this;

				if (this[KEY_NEGATIVE] || (KEY_TYPE in this) || this.is_0() || this.is_0(1) || (KEY_TYPE in exponent) || exponent.is_0())
					// 不處理虛數與複數。
					// do simulation: 模擬與 NaN 等極端數字作運算。
					return this.assignment(Math.pow(this.valueOf(TYPE_TEST), exponent.valueOf(TYPE_TEST)));

				if (exponent[KEY_NEGATIVE]) {
					//負數
					delete exponent[KEY_NEGATIVE];
					exponent = this.clone().power(exponent);
					return this.assignment((new Integer(1)).division(exponent, precision));
				}

				var integer_part = exponent.valueOf() | 0, error_digits = 2, _precision = (precision || 2 * DECIMAL_BASE_LENGTH) + error_digits;
				if (!Number.isSafeInteger(integer_part)) {
					library_namespace.error('power: Invalid exponent: [' + exponent + '] (exponent too large, overflowed / underflowed).');
					return this.assignment(this.compare(1) < 0 ? 0 : Infinity);
				}

				// 至此特殊值處理完畢。


				exponent = exponent[KEY_EXPONENT] === 0 ? 0
				// has a fractional part (有小數部分)
				// v ^ e = exp ^ (e ln v)
				: Integer_exp(exponent.add(-integer_part).multiply(ln(this, _precision)), _precision);

				if (integer_part) {
					//處理 integer part 整數部分。
					_precision = precision && 2 * (precision + error_digits);
					for (var product = this ; ;) {
						if (integer_part % 2 === 1)
							if (product !== this) {
								// array multiply: this *= product
								this.multiply(product);
								if (_precision && this.length > _precision)
									this.to_precision(_precision);
							} else if (1 < integer_part)
								product = this.clone();

						if ((integer_part >>= 1) === 0)
							break;

						product.square();
					}

					if (exponent)
						this.multiply(exponent);

				} else
					// assert: exponent != 0
					this.assignment(exponent);


				if (precision)
					(new Integer(this, DEFAULT_RADIX)).to_precision(precision).clone(this);

				return this;
			}


			// https://en.wikipedia.org/wiki/Pi
			// https://en.wikipedia.org/wiki/List_of_formulae_involving_%CF%80#Efficient_infinite_series
			// calculate mathematical constant π ≈
			function Integer_PI(precision) {
				return summation('PI', function (PI) {
					for (var index = 0, addend = PI.clone() ;
						!(addend = addend.multiply(++index).division(2 * index + 1)).is_0() ;)
						PI.add(addend);
				}, precision, 2, 2);
			}

			// ---------------------------------------------------------------------//

			return Integer;
		}

	});
