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