1 
  2 /**
  3  * @name	CeL function for math
  4  * @fileoverview
  5  * 本檔案包含了數學演算相關的 functions。
  6  * @since	
  7  */
  8 
  9 /*
 10 TODO:
 11 大數計算
 12 方程式圖形顯示 by SVG
 13 */
 14 
 15 
 16 
 17 if (typeof CeL === 'function')
 18 CeL.setup_module('data.math',
 19 {
 20 require : 'data.split_String_to_Object',
 21 code : function(library_namespace, load_arguments) {
 22 
 23 //	requiring
 24 var split_String_to_Object;
 25 eval(library_namespace.use_function(this));
 26 
 27 
 28 
 29 /**
 30  * null module constructor
 31  * @class	數學相關的 functions
 32  */
 33 CeL.data.math
 34 = function() {
 35 	//	null module constructor
 36 };
 37 
 38 /**
 39  * for JSDT: 有 prototype 才會將之當作 Class
 40  */
 41 CeL.data.math
 42 .prototype = {
 43 };
 44 
 45 
 46 
 47 
 48 
 49 /*
 50 	Math	---------------------------------------------------------------
 51 */
 52 
 53 /*
 54 //{var v=Math.LN2,d=mutual_division(v),q=to_rational_number(v);alert('值	'+v+'\n序列	'+d+'\n近似值	'+q[0]+' / '+q[1]+'\n約	'+(q=q[0]/q[1])+'\n值-近似	'+(q-=v)+'\n差'+(Math.abs(q=10000*q/v)>1?'萬分之'+q.to_fixed(2)+' ( '+q+' / 10000 )':'億分之'+(q*=10000).to_fixed(2)+' ( '+q+' / 100000000 )'),0,'近似值	'+v);}
 55 
 56 //{var d=new Date,a=.142857,b=1000000,i=0,c;for(i=0;i<10000;i++)c=mutual_division(a);alert(c+'\n'+gDate(new Date-d));}
 57 */
 58 
 59 CeL.data.math
 60 .
 61 /**
 62  * 輾轉相除 n1/n2 或 小數 n1/1 轉成 整數/整數
 63  * @param {Number} n1	number 1
 64  * @param {Number} [n2]	number 2
 65  * @param {Number} times	max 次數, 1,2,..
 66  * @return	{Array}	連分數序列 ** 負數視 _.mutual_division.done 而定!
 67  */
 68 mutual_division = function mutual_division(n1, n2, times) {
 69 	var q = [], c;
 70 	if (isNaN(times) || times <= 0)
 71 		times = 80;
 72 	if (!n2 || isNaN(n2))
 73 		n2 = 1;
 74 
 75 	if (n1 != Math.floor(n1)) {
 76 		c = n1;
 77 		var i = 9, f = n2;
 78 		while (i--)
 79 			//	以整數運算比較快!這樣會造成整數多4%,浮點數多1/3倍的時間,但仍值得。
 80 			if (f *= 10, c *= 10, c === Math.floor(c)) {
 81 				n1 = c, n2 = f;
 82 				break;
 83 			}
 84 	}
 85 
 86 	//	連分數負數之處理。更沒問題的: (n1 < 0?1:0) ^ (n2 < 0?1:0)
 87 	if (_.mutual_division.mode && ((n1 < 0) ^ (n2 < 0))) {
 88 		// 使兩數皆為正
 89 		if (n2 < 0)
 90 			n2 = -n2;
 91 		else
 92 			n1 = -n1;
 93 
 94 		q.push(-(1 + (n1 - (c = n1 % n2)) / n2));
 95 		n1 = n2, n2 -= c;
 96 	}
 97 
 98 	/* old:
 99 	 while(b&&n--)
100 	  d.push((a-(c=a%b))/b),a=b,b=c;	//	2.08s@10000	可能因為少設定(=)一次c所以較快。但(若輸入不為整數)不確保d為整數?用Math.floor((a-(c=a%b))/b)可確保,速度與下式一樣快。
101 	  //d.push(c=Math.floor(a/b)),c=a-b*c,a=b,b=c;	//	2.14s@10000:mutual_division(.142857)
102 	  //d.push(Math.floor(a/b)),b=a%(c=b),a=c;	//	2.2s@10000
103 	 //if(n)d.push(0);
104 	*/
105 
106 	//	2.4s@10000	可能因為少設定(=)一次c所以較快。但(若輸入不為整數)不確保d為整數?用Math.floor((a-(c=a%b))/b)可確保,速度與下式一樣快。
107 	while (times--)
108 		if (n2)
109 			q.push((n1 - (c = n1 % n2)) / n2), n1 = n2, n2 = c;
110 		else {
111 			//	[ .. , done mark, (最後非零的餘數。若原 n1, n2 皆為整數,則此值為 GCD。但請注意:這邊是已經經過前面為了以整數運算,增加倍率過的數值!!) ]
112 			q.push(_.mutual_division.done, n1);
113 			//library_namespace.debug('done: ' + q);
114 			break;
115 		}
116 
117 	//	2.26s@10000
118 	//while(b&&n--)if(d.push((a-(c=a%b))/b),a=b,!(b=c)){d.push(0);break;}
119 
120 	//var m=1;c=1;while(m&&n--)d.push(m=++c%2?b?(a-(a%=b))/b:0:a?(b-(b%=a))/a:0);//bug
121 
122 	return q;
123 };
124 CeL.data.math
125 .
126 mutual_division.done = -7;//''
127 
128 CeL.data.math
129 .
130 /**
131  * !!mode:連分數處理,對負數僅有最初一數為負。
132  */
133 mutual_division.mode = 0;
134 
135 CeL.data.math
136 .
137 /**
138  * 取得連分數序列的數值
139  * @param {Array} sequence	序列
140  * @param {Number} [max_no]	取至第 max_no 個
141  * @requires	mutual_division.done
142  * @return
143  * @see
144  * var a=continued_fraction([1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2]);
145  * alert(a+'\n'+a[0]/a[1]+'\n'+Math.SQRT2+'\n'+(Math.SQRT2-a[0]/a[1])+'\n'+mutual_division(a[0],a[1]));
146  */
147 continued_fraction = function(sequence, max_no) {
148 	if (!library_namespace.is_Array(sequence) || !sequence.length)
149 		return sequence;
150 
151 	if (sequence[sequence.length - 2] === _.mutual_division.done)
152 		sequence.length -= 2;
153 
154 	if (sequence.length < 1)
155 		return sequence;
156 
157 	if (!max_no/* ||max_no<2 */|| max_no > sequence.length)
158 		max_no = sequence.length;
159 
160 	var a, b;
161 	if (max_no % 2)
162 		b = 1, a = 0;
163 	else
164 		a = 1, b = 0;
165 	//sequence[max_no++]=1;if(--max_no%2)b=sequence[max_no],a=s[--max_no];else a=sequence[max_no],b=sequence[--max_no];
166 
167 	//library_namespace.debug('a=' + a + ', b=' + b + ', max_no=' + max_no);
168 	while (max_no--)
169 		if (max_no % 2)
170 			b += a * sequence[max_no];
171 		else
172 			a += b * sequence[max_no];
173 	//library_namespace.debug('a=' + a + ', b=' + b);
174 	return [ a, b ];
175 };
176 
177 
178 CeL.data.math
179 .
180 /**
181  * The best rational approximation. 取得值最接近之有理數 (use 連分數 continued fraction), 取近似值.
182  * c.f., 調日法
183  * 在分子或分母小於下一個漸進分數的分數中,其值是最接近精確值的近似值。
184  * @example
185  * to_rational_number(4088/783)
186  * @param {Number} number	number
187  * @param {Number} [rate]	比例在 rate 以上
188  * @param {Number} [max_no]	最多取至序列第 max_no 個
189  * 					TODO : 並小於 l: limit
190  * @return	[分子, 分母, 誤差]
191  * @requires	mutual_division,continued_fraction
192  * @see
193  * http://en.wikipedia.org/wiki/Continued_fraction#Best_to_rational_numbers
194  */
195 to_rational_number = function(number, rate, max_no) {
196 	if (!rate)
197 		//	This is a magic number: 我們無法準確得知其界限為何。
198 		rate = 65536;
199 	var d = _.mutual_division(number, 1, max_no && max_no > 0 ? max_no : 20),
200 	i = 0, a, b = d[0], done = _.mutual_division.done;
201 
202 	if (!b)
203 		b = d[++i];
204 	while (++i < d.length && (a = d[i]) !== done)
205 		if (a / b < rate)
206 			b = a;
207 		else
208 			break;
209 
210 	if(0)
211 		library_namespace.debug(
212 			number + ' ' +
213 			//	連分數表示
214 			(d.length > 1 && d[d.length - 2] === _.mutual_division.done ?
215 				'=' + ' [<em>' + d[0] + ';' + d.slice(1, i).join(', ') + '</em>'
216 					+ (i < d.length - 2 ? ', ' + d.slice(i, -2).join(', ') : '')
217 					+ '] .. ' + d.slice(-1) :
218 				//	約等於的符號是≈或≒,不等於的符號是≠。
219 				//	http://zh.wikipedia.org/wiki/%E7%AD%89%E4%BA%8E
220 				'≈' + ' [<em>' + d[0] + ';' + d.slice(1, i).join(', ') + '</em>'
221 					+ (i < d.length ? ', ' + d.slice(i).join(', ') : '') + ']: '
222 					+ d.length + ',' + i + ',' + d[i]
223 			)
224 		);
225 	d = _.continued_fraction(d, i);
226 	//library_namespace.debug('→ ' + d[0] + '/' + d[1]);
227 	if (d[1] < 0)
228 		d[0] = -d[0], d[1] = -d[1];
229 
230 	return [ d[0], d[1], d[0] / d[1] - number ];
231 };
232 
233 
234 /*	最大公因數/公約數	 Greatest Common Divisor
235 
236 usage:
237 	gcd(6,9)
238 	GCD([5,3,8,2,6,9])
239 */
240 //_gcd[generateCode.dLK]='mutual_division,mutual_division_done';
241 function _gcd(a,b){
242  if(isNaN(a)||isNaN(b))
243   return isNaN(b)?a:b;
244 
245  var d=_.mutual_division(a,b);
246  a=d.pop();
247  if(d.pop()===_.mutual_division.done)
248   return a;
249 }
250 
251 CeL.data.math
252 .
253 /**
254  * Get GCD of 2 numbers
255  * @param n1	number 1
256  * @param n2	number 2
257  * @return	GCD of the 2 numbers
258  */
259 gcd = function(n1, n2) {
260 	/*
261 	if (isNaN(a))
262 		return b;
263 	*/
264 	//	必要!
265 	if (!n2 || isNaN(n2))
266 		return n1;
267 
268 	//	也可最後再 Math.abs
269 	/*
270 	if (a < 0)
271 		a = -a;
272 	if (b < 0)
273 		b = -b;
274 	*/
275 
276 	//	Euclidean algorithm
277 	var r;
278 	while (r = n1 % n2)
279 		n1 = n2, n2 = r;
280 	return n2 < 0 ? -n2 : n2;
281 };
282 
283 //GCD[generateCode.dLK]='gcd';
284 function GCD(numA){
285  var i=1,g=numA[0];
286  for(;i<numA.length;i++)
287   if(!isNaN(numA[i]))
288    g=gcd(g,numA[i]);
289  return g;
290 }
291 /*	最小公倍數	 Least Common Multiple
292 
293 usage:
294 	lcm(6,9)
295 	lcm([5,3,8,2,6,9])
296 
297 TODO:
298 更快的方法:
299 短除法
300 一次算出 GCD, LCM
301 */
302 //lcm[generateCode.dLK]='gcd';
303 function lcm(a,b){
304  var l,g,i=1;
305  if( typeof a=='object' && !isNaN(l=a[0]) ){
306   while(i<a.length)
307    l=lcm(l,a[i++]);
308   return l;
309  }
310 
311  if( (g=gcd(a,b)) && !isNaN(g) )
312   return a/g*b;
313 }
314 
315 
316 /*
317 http://www.math.umbc.edu/~campbell/NumbThy/Class/Programming/JavaScript.html
318 http://aoki2.si.gunma-u.ac.jp/JavaScript/
319 */
320 
321 CeL.data.math
322 .
323 /**
324  * 得到平方數,相當於 Math.floor(Math.sqrt(number)).
325  * get integer square root
326  * @param {Number} positive number
327  * @return	r, r^2 <= number < (r+1)^2
328  * @example
329  * var p = 20374345, q = CeL.math.floor_sqrt(p = p * p - 1); CeL.log(q + '<br/>' + (q * q) + '<br/>' + p + '<br/>' + (++q * q));
330  * @see
331  * <a href="http://www.azillionmonkeys.com/qed/sqroot.html" accessdate="2010/3/11 18:37">Paul Hsieh's Square Root page</a>
332  * <a href="http://www.embeddedrelated.com/usenet/embedded/show/114789-1.php" accessdate="2010/3/11 18:34">Suitable Integer Square Root Algorithm for 32-64-Bit Integers on Inexpensive Microcontroller? | Comp.Arch.Embedded | EmbeddedRelated.com</a>
333  */
334 floor_sqrt = function(number){
335 	if (isNaN(number = Math.floor(number)))
336 		return;
337 	var g = 0, v, h, t;
338 	while ((t = g << 1) < (v = number - g * g)) {
339 		//library_namespace.debug(t + ', ' + v);
340 		h = 1;
341 		while (h * (h + t) <= v)
342 			// 因為型別轉關係,還是保留 << 而不用 *2
343 			h <<= 1;//h *= 2;
344 		g += h >> 1;//h / 2;//
345 	}
346 	//library_namespace.debug('end: ' + t + ', ' + v);
347 	return g;
348 };
349 
350 
351 CeL.data.math
352 .
353 /**
354  * 取得某數的質因數,因式分解/素因子分解, factorization, get floor factor.
355  * 唯一分解定理(The Unique Factorization Theorem)告訴我們素因子分解是唯一的,這即是稱為算術基本定理 (The Fundamental Theorem of Arithmeric) 的數學金科玉律。
356  * @param {Number} number
357  * @return	{Array} [prime1,power1,prime2,power2,..]
358  * @see
359  * <a href="http://homepage2.nifty.com/m_kamada/math/10001.htm" accessdate="2010/3/11 18:7">Factorizations of 100...001</a>
360  * @requires	floor_sqrt
361  */
362 factorization = function(number) {
363 	var f = 2, p, a, l, r = [];
364 	if (isNaN(number) || number < 1 || number >
365 			/*
366 			 * javascript 可以表示的最大整數值
367 			 * 10^21-2^16-1 = 999999999999999934463
368 			 * @see
369 			 * http://www.highdots.com/forums/javascript/how-js-numbers-represented-internally-166538-4.html
370 			 */
371 			999999999999999934469)
372 		return;
373 	number = Math.floor(number);
374 
375 	// 2,3
376 	while (number > 1) {
377 		if (number % f === 0) {
378 			p = 0;
379 			do
380 				number /= f, p++;
381 			while (number % f === 0); // do{n/=f,p++;}while(n%f==0);
382 			r.push(f, p);
383 		}
384 		if (++f > 3)
385 			break;
386 	}
387 
388 	a = 4, f = 5, l = _.floor_sqrt(number); // 5-初始化
389 	while (number > 1) {
390 		if (f > l) {
391 			r.push(number, 1);
392 			break;
393 		}
394 		// document.write('<br/>'+f+','+n);
395 		if (number % f === 0) {
396 			p = 0;
397 			do {
398 				number /= f, p++;
399 			} while (number % f === 0);
400 			l = _.floor_sqrt(number), r.push(f, p);
401 		}
402 		f += a = a === 2 ? 4 : 2;
403 	}
404 	return r;
405 };
406 
407 /*	test
408 function count(n){
409 var a=factorization(n),s='',v=1;
410 if(a){
411  for(var i=0;i<a.length;i+=2){s+='*'+a[i]+(a[i+1]>1?'^'+a[i+1]:'');v*=Math.pow(a[i],a[i+1]);}
412  s=s.substr(1)+'='+v+'='+n;
413 }else s='error! '+n;
414 document.getElementById('result').value+=s+'\n-------------------------------------------\n';
415 }
416 */
417 
418 
419 /*	猜測一個數可能的次方數。	2005/2/18 19:20未完成
420 	type=0:整數,1:有理數
421 	return [base分子,base分母,exponent分子,exponent分母]
422 */
423 function to_exponent(num,type){
424  var bn,bd,en=1,ed,sq=[1,num],t,q,error=1e-9,g=function(n){q=_.to_rational_number(n,99999);if((!type||q[1]==1)&&!(q[0]>99999&&q[1]>99999)&&q[2]/n<error)bn=q[0],bd=q[1],ed=t;};//error:誤差
425 
426  if(!ed)g(sq[t=1]);
427  if(!ed)g(sq[t=2]=sq[1]*sq[1]);
428  if(!ed)g(sq[t=3]=sq[1]*sq[2]);
429  if(!ed)g(sq[t=4]=sq[2]*sq[2]);
430  if(!ed)g(sq[t=5]=sq[2]*sq[3]);
431  if(!ed)bn=num,bd=ed=1;
432 
433  return [bn,bd,en,ed];
434 }
435 //var t=to_exponent(Math.pow(2/3,1/1));alert(t[0]+'/'+t[1]+'^'+t[2]+'/'+t[3]);
436 
437 
438 
439 
440 /*
441 for 出題
442 
443 runCode.setR=0;
444 for(var i=0,j,t,s,n_e;i<10;){
445  t=2000+8000*Math.random();
446  s=get_random_prime.get_different_number_set(3,t,t/8);
447  if(s.LCM>9999)continue;
448  n_e=[];
449  n_e[s.GCD]=1;
450  for(j=0;j<s.length;j++)
451   if(n_e[s[j]])continue;
452   else n_e[s[j]]=1;
453  sl([s.GCD,s.LCM]+'<b style="color:#c4a">;</b> '+s);i++;
454 }
455 
456 */
457 
458 //	求乘積
459 function get_product(nums,till){	//	num array, 乘到比till小就回傳
460  var p=1,i=0,l=nums.length;
461  for(;i<l;i++){
462   if(till&&p*nums[i]>till)break;
463   p*=nums[i];
464  }
465  return p;
466 }
467 
468 
469 //	2009/10/21 11:57:47
470 //get_random_prime[generateCode.dLK]='get_product';
471 get_random_prime.primes=[2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,487,491,499,503,509,521,523,541,547,557,563,569,571,577,587,593,599,601,607,613,617,619,631,641,643,647,653,659,661,673,677,683,691,701,709,719,727,733,739,743,751,757,761,769,773,787,797,809,811,821,823,827,829,839,853,857,859,863,877,881,883,887,907,911,919,929,937,941,947,953,967,971,977,983,991,997];
472 function get_random_prime(count,exclude,all_different){	//	個數, 排除
473  var _f=arguments.callee,i,j,p=[],l;
474  if(!count||count<1)count=1;
475  if(!_f.excluded)
476   _f.excluded=[];
477  if(exclude)exclude=[];
478 
479  for(j=0;j<count;j++){
480   l=80;	//	timeout
481   do{
482    i=Math.round(10*Math.tan(Math.random()*1.5));
483    if(!--l)return;	//	timeout
484   }while(_f.excluded[i]);
485   p.push(_f.primes[i]);
486   if(exclude)exclude.push(i);
487  }
488 
489  //	選完才排除本次選的
490  if(exclude)
491   for(j=0,l=exclude.length;j<l;j++){
492    i=exclude[j];
493    if(_f.excluded[i])_f.excluded[i]++;
494    else _f.excluded[i]=1;
495   }
496 
497  return count==1?p[0]:p;
498 }
499 
500 //	return [GCD, n1, n2, ..]
501 get_random_prime.get_different_number_set=function(count,till,GCD_till){
502  delete this.excluded;
503  if(!GCD_till)GCD_till=1e5;
504  if(!till)till=1e5;
505 
506  var GCD=get_product(this(20,1),GCD_till),na=[],n_e=[],n,i=0,out;
507  n_e[GCD]=1;
508 
509  for(;i<count;i++){
510   out=80;	//	timeout
511   do{
512    n=this(20);
513    n.unshift(GCD);
514    n=get_product(n,till);
515   }while(n_e[n]&&--out);
516   n_e[n]=1;
517   na.push(n);
518  }
519 
520  if(typeof lcm=='function')
521   na.LCM=lcm(na);
522  na.GCD=GCD;
523  return na;
524 };
525 
526 
527 
528 CeL.data.math
529 .
530 /**
531  * VBScript has a Hex() function but JScript does not.
532  * @param {Number} number
533  * @return	{String} number in hex
534  * @example
535  * alert('0x'+CeL.hex(16725))
536  */
537 hex = function(number) {
538 	return (number < 0 ? number + 0x100000000 : number - 0).toString(16);
539 }
540 
541 CeL.data.math
542 .
543 /**
544  * 補數計算。
545  * 正數的補數即為自身。若要求得互補之後的數字,請設成負數。
546  * @param {Number} number
547  * @return	{Number} base	1: 1's Complement, 2: 2's Complement, (TODO: 3, 4, ..)
548  * @example
549  * alert(complement())
550  * @see
551  * http://www.tomzap.com/notes/DigitalSystemsEngEE316/1sAnd2sComplement.pdf
552  * http://en.wikipedia.org/wiki/Method_of_complements
553  * http://en.wikipedia.org/wiki/Signed_number_representations
554  * @since	2010/3/12 23:47:52
555  */
556 complement = function() {
557 	return this.from.apply(this, arguments);
558 };
559 
560 _.complement.prototype = {
561 
562 base : 2,
563 
564 //	1,2,..
565 bits : 8,
566 
567 //	radix complement or diminished radix complement.
568 //	http://en.wikipedia.org/wiki/Method_of_complements
569 diminished : 0,
570 
571 /**
572  * 正負符號.
573  * 正: 0/false,
574  * 負 negative value:!=0 / true
575  */
576 sign : 0,
577 
578 //	get the value
579 valueOf : function() {
580 	return this.sign ? -this.value : this.value;
581 },
582 
583 /**
584  * set value
585  */
586 set : function(value) {
587 	var m = Number(value), a = Math.abs(m);
588 	if (isNaN(m) || m && a < 1e-8 || a > 1e12){
589 		library_namespace.debug('complement.set: error number: ' + value);
590 		return;
591 	}
592 
593 	this.sign = m < 0;
594 	// this.value 僅有正值
595 	this.value = a;
596 
597 	return this;
598 },
599 
600 
601 /**
602  * input
603  */
604 from : function(number, base, diminished) {
605 	//	正規化
606 	number = ('' + (number||0)).replace(/\s+$|^[\s0]+/g, '') || '0';
607 	//library_namespace.debug(number + ':' + number.length + ',' + this.bits);
608 
609 	//	整數部分位數
610 	var value = number.indexOf('.'), tmp;
611 	if (value == -1)
612 		value = number.length;
613 	//	TODO: not good
614 	if (value > this.bits)
615 		//throw 'overflow';
616 		library_namespace.err('complement.from: overflow: ' + value);
617 
618 	if (typeof diminished === 'undefined')
619 		//	illegal setup
620 		diminished = this.diminished;
621 	else
622 		this.diminished = diminished;
623 
624 	if ((base = Math.floor(base)) && base > 0){
625 		if (base === 1)
626 			base = 2, this.diminished = 1;
627 		this.base = base;
628 	}else
629 		//	illegal base
630 		base = this.base;
631 	//library_namespace.debug(base + "'s Complement");
632 
633 	//	TODO: 僅對 integer 有效
634 	value = parseInt(number, base);
635 	tmp = Math.pow(base, this.bits - 1);
636 	if (value >= tmp * base)
637 		//throw 'overflow';
638 		library_namespace.err('complement.from: overflow: ' + value);
639 
640 	//library_namespace.debug('compare ' + value + ',' + tmp);
641 	if (value < tmp)
642 		this.sign = 0;
643 	else
644 		//library_namespace.debug('負數 ' + (tmp * base - (diminished ? 1 : 0)) + '-'+ value+'='+(tmp * base - (diminished ? 1 : 0) - value)),
645 		this.sign = 1,
646 		value = tmp * base - (diminished ? 1 : 0) - value;
647 
648 	this.value = value;
649 	//library_namespace.debug(number + ' → '+this.valueOf());
650 
651 	return this;
652 },
653 
654 /**
655  * output
656  */
657 to : function(base, diminished) {
658 	if (!(base = Math.floor(base)) || base < 1)
659 		base = this.base;
660 	else if (base === 1)
661 		base = 2, diminished = 1;
662 	if (typeof diminished === 'undefined')
663 		diminished = this.diminished;
664 
665 	var value = this.value, tmp = Math.pow(base, this.bits - 1);
666 	if (value > tmp || value === tmp && (diminished || !this.sign))
667 		//throw 'overflow';
668 		library_namespace.err('complement.to: overflow: ' + (this.sign ? '-' : '+') + value);
669 
670 	if (this.sign){
671 		tmp *= base;
672 		if (diminished)
673 			//	TODO: 僅對 integer 有效
674 			tmp--;
675 		//library_namespace.debug('負數 ' + value + ',sum=' + tmp);
676 		// 負數,添上兩補數之和
677 		value = tmp - value;
678 	}
679 
680 	//library_namespace.debug('value: ' + (this.sign ? '-' : '+') + value);
681 
682 	value = value.toString(Math.max(2, this.base));
683 
684 	return value;
685 }
686 
687 };
688 
689 _.complement.prototype.toString = _.complement.prototype.to;
690 
691 
692 /*
693 	↑Math	---------------------------------------------------------------
694 */
695 
696 
697 
698 
699 return (
700 	CeL.data.math
701 );
702 }
703 
704 
705 });
706 
707