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