12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922
  1. //-----------------------------------------------------------------
  2. //-----------------------------------------------------------------
  3. function md5 (str) {
  4. // Calculate the md5 hash of a string
  5. //
  6. // version: 1109.2015
  7. // discuss at: http://phpjs.org/functions/md5
  8. // + original by: Webtoolkit.info (http://www.webtoolkit.info/)
  9. // + namespaced by: Michael White (http://getsprink.com)
  10. // + tweaked by: Jack
  11. // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  12. // + input by: Brett Zamir (http://brett-zamir.me)
  13. // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  14. // - depends on: utf8_encode
  15. // * example 1: md5('Kevin van Zonneveld');
  16. // * returns 1: '6e658d4bfcb59cc13f96c14450ac40b9'
  17. var xl;
  18. var rotateLeft = function (lValue, iShiftBits) {
  19. return (lValue << iShiftBits) | (lValue >>> (32 - iShiftBits));
  20. };
  21. var addUnsigned = function (lX, lY) {
  22. var lX4, lY4, lX8, lY8, lResult;
  23. lX8 = (lX & 0x80000000);
  24. lY8 = (lY & 0x80000000);
  25. lX4 = (lX & 0x40000000);
  26. lY4 = (lY & 0x40000000);
  27. lResult = (lX & 0x3FFFFFFF) + (lY & 0x3FFFFFFF);
  28. if (lX4 & lY4) {
  29. return (lResult ^ 0x80000000 ^ lX8 ^ lY8);
  30. }
  31. if (lX4 | lY4) {
  32. if (lResult & 0x40000000) {
  33. return (lResult ^ 0xC0000000 ^ lX8 ^ lY8);
  34. } else {
  35. return (lResult ^ 0x40000000 ^ lX8 ^ lY8);
  36. }
  37. } else {
  38. return (lResult ^ lX8 ^ lY8);
  39. }
  40. };
  41. var _F = function (x, y, z) {
  42. return (x & y) | ((~x) & z);
  43. };
  44. var _G = function (x, y, z) {
  45. return (x & z) | (y & (~z));
  46. };
  47. var _H = function (x, y, z) {
  48. return (x ^ y ^ z);
  49. };
  50. var _I = function (x, y, z) {
  51. return (y ^ (x | (~z)));
  52. };
  53. var _FF = function (a, b, c, d, x, s, ac) {
  54. a = addUnsigned(a, addUnsigned(addUnsigned(_F(b, c, d), x), ac));
  55. return addUnsigned(rotateLeft(a, s), b);
  56. };
  57. var _GG = function (a, b, c, d, x, s, ac) {
  58. a = addUnsigned(a, addUnsigned(addUnsigned(_G(b, c, d), x), ac));
  59. return addUnsigned(rotateLeft(a, s), b);
  60. };
  61. var _HH = function (a, b, c, d, x, s, ac) {
  62. a = addUnsigned(a, addUnsigned(addUnsigned(_H(b, c, d), x), ac));
  63. return addUnsigned(rotateLeft(a, s), b);
  64. };
  65. var _II = function (a, b, c, d, x, s, ac) {
  66. a = addUnsigned(a, addUnsigned(addUnsigned(_I(b, c, d), x), ac));
  67. return addUnsigned(rotateLeft(a, s), b);
  68. };
  69. var convertToWordArray = function (str) {
  70. var lWordCount;
  71. var lMessageLength = str.length;
  72. var lNumberOfWords_temp1 = lMessageLength + 8;
  73. var lNumberOfWords_temp2 = (lNumberOfWords_temp1 - (lNumberOfWords_temp1 % 64)) / 64;
  74. var lNumberOfWords = (lNumberOfWords_temp2 + 1) * 16;
  75. var lWordArray = new Array(lNumberOfWords - 1);
  76. var lBytePosition = 0;
  77. var lByteCount = 0;
  78. while (lByteCount < lMessageLength) {
  79. lWordCount = (lByteCount - (lByteCount % 4)) / 4;
  80. lBytePosition = (lByteCount % 4) * 8;
  81. lWordArray[lWordCount] = (lWordArray[lWordCount] | (str.charCodeAt(lByteCount) << lBytePosition));
  82. lByteCount++;
  83. }
  84. lWordCount = (lByteCount - (lByteCount % 4)) / 4;
  85. lBytePosition = (lByteCount % 4) * 8;
  86. lWordArray[lWordCount] = lWordArray[lWordCount] | (0x80 << lBytePosition);
  87. lWordArray[lNumberOfWords - 2] = lMessageLength << 3;
  88. lWordArray[lNumberOfWords - 1] = lMessageLength >>> 29;
  89. return lWordArray;
  90. };
  91. var wordToHex = function (lValue) {
  92. var wordToHexValue = "",
  93. wordToHexValue_temp = "",
  94. lByte, lCount;
  95. for (lCount = 0; lCount <= 3; lCount++) {
  96. lByte = (lValue >>> (lCount * 8)) & 255;
  97. wordToHexValue_temp = "0" + lByte.toString(16);
  98. wordToHexValue = wordToHexValue + wordToHexValue_temp.substr(wordToHexValue_temp.length - 2, 2);
  99. }
  100. return wordToHexValue;
  101. };
  102. var x = [],
  103. k, AA, BB, CC, DD, a, b, c, d, S11 = 7,
  104. S12 = 12,
  105. S13 = 17,
  106. S14 = 22,
  107. S21 = 5,
  108. S22 = 9,
  109. S23 = 14,
  110. S24 = 20,
  111. S31 = 4,
  112. S32 = 11,
  113. S33 = 16,
  114. S34 = 23,
  115. S41 = 6,
  116. S42 = 10,
  117. S43 = 15,
  118. S44 = 21;
  119. str = this.utf8_encode(str);
  120. x = convertToWordArray(str);
  121. a = 0x67452301;
  122. b = 0xEFCDAB89;
  123. c = 0x98BADCFE;
  124. d = 0x10325476;
  125. xl = x.length;
  126. for (k = 0; k < xl; k += 16) {
  127. AA = a;
  128. BB = b;
  129. CC = c;
  130. DD = d;
  131. a = _FF(a, b, c, d, x[k + 0], S11, 0xD76AA478);
  132. d = _FF(d, a, b, c, x[k + 1], S12, 0xE8C7B756);
  133. c = _FF(c, d, a, b, x[k + 2], S13, 0x242070DB);
  134. b = _FF(b, c, d, a, x[k + 3], S14, 0xC1BDCEEE);
  135. a = _FF(a, b, c, d, x[k + 4], S11, 0xF57C0FAF);
  136. d = _FF(d, a, b, c, x[k + 5], S12, 0x4787C62A);
  137. c = _FF(c, d, a, b, x[k + 6], S13, 0xA8304613);
  138. b = _FF(b, c, d, a, x[k + 7], S14, 0xFD469501);
  139. a = _FF(a, b, c, d, x[k + 8], S11, 0x698098D8);
  140. d = _FF(d, a, b, c, x[k + 9], S12, 0x8B44F7AF);
  141. c = _FF(c, d, a, b, x[k + 10], S13, 0xFFFF5BB1);
  142. b = _FF(b, c, d, a, x[k + 11], S14, 0x895CD7BE);
  143. a = _FF(a, b, c, d, x[k + 12], S11, 0x6B901122);
  144. d = _FF(d, a, b, c, x[k + 13], S12, 0xFD987193);
  145. c = _FF(c, d, a, b, x[k + 14], S13, 0xA679438E);
  146. b = _FF(b, c, d, a, x[k + 15], S14, 0x49B40821);
  147. a = _GG(a, b, c, d, x[k + 1], S21, 0xF61E2562);
  148. d = _GG(d, a, b, c, x[k + 6], S22, 0xC040B340);
  149. c = _GG(c, d, a, b, x[k + 11], S23, 0x265E5A51);
  150. b = _GG(b, c, d, a, x[k + 0], S24, 0xE9B6C7AA);
  151. a = _GG(a, b, c, d, x[k + 5], S21, 0xD62F105D);
  152. d = _GG(d, a, b, c, x[k + 10], S22, 0x2441453);
  153. c = _GG(c, d, a, b, x[k + 15], S23, 0xD8A1E681);
  154. b = _GG(b, c, d, a, x[k + 4], S24, 0xE7D3FBC8);
  155. a = _GG(a, b, c, d, x[k + 9], S21, 0x21E1CDE6);
  156. d = _GG(d, a, b, c, x[k + 14], S22, 0xC33707D6);
  157. c = _GG(c, d, a, b, x[k + 3], S23, 0xF4D50D87);
  158. b = _GG(b, c, d, a, x[k + 8], S24, 0x455A14ED);
  159. a = _GG(a, b, c, d, x[k + 13], S21, 0xA9E3E905);
  160. d = _GG(d, a, b, c, x[k + 2], S22, 0xFCEFA3F8);
  161. c = _GG(c, d, a, b, x[k + 7], S23, 0x676F02D9);
  162. b = _GG(b, c, d, a, x[k + 12], S24, 0x8D2A4C8A);
  163. a = _HH(a, b, c, d, x[k + 5], S31, 0xFFFA3942);
  164. d = _HH(d, a, b, c, x[k + 8], S32, 0x8771F681);
  165. c = _HH(c, d, a, b, x[k + 11], S33, 0x6D9D6122);
  166. b = _HH(b, c, d, a, x[k + 14], S34, 0xFDE5380C);
  167. a = _HH(a, b, c, d, x[k + 1], S31, 0xA4BEEA44);
  168. d = _HH(d, a, b, c, x[k + 4], S32, 0x4BDECFA9);
  169. c = _HH(c, d, a, b, x[k + 7], S33, 0xF6BB4B60);
  170. b = _HH(b, c, d, a, x[k + 10], S34, 0xBEBFBC70);
  171. a = _HH(a, b, c, d, x[k + 13], S31, 0x289B7EC6);
  172. d = _HH(d, a, b, c, x[k + 0], S32, 0xEAA127FA);
  173. c = _HH(c, d, a, b, x[k + 3], S33, 0xD4EF3085);
  174. b = _HH(b, c, d, a, x[k + 6], S34, 0x4881D05);
  175. a = _HH(a, b, c, d, x[k + 9], S31, 0xD9D4D039);
  176. d = _HH(d, a, b, c, x[k + 12], S32, 0xE6DB99E5);
  177. c = _HH(c, d, a, b, x[k + 15], S33, 0x1FA27CF8);
  178. b = _HH(b, c, d, a, x[k + 2], S34, 0xC4AC5665);
  179. a = _II(a, b, c, d, x[k + 0], S41, 0xF4292244);
  180. d = _II(d, a, b, c, x[k + 7], S42, 0x432AFF97);
  181. c = _II(c, d, a, b, x[k + 14], S43, 0xAB9423A7);
  182. b = _II(b, c, d, a, x[k + 5], S44, 0xFC93A039);
  183. a = _II(a, b, c, d, x[k + 12], S41, 0x655B59C3);
  184. d = _II(d, a, b, c, x[k + 3], S42, 0x8F0CCC92);
  185. c = _II(c, d, a, b, x[k + 10], S43, 0xFFEFF47D);
  186. b = _II(b, c, d, a, x[k + 1], S44, 0x85845DD1);
  187. a = _II(a, b, c, d, x[k + 8], S41, 0x6FA87E4F);
  188. d = _II(d, a, b, c, x[k + 15], S42, 0xFE2CE6E0);
  189. c = _II(c, d, a, b, x[k + 6], S43, 0xA3014314);
  190. b = _II(b, c, d, a, x[k + 13], S44, 0x4E0811A1);
  191. a = _II(a, b, c, d, x[k + 4], S41, 0xF7537E82);
  192. d = _II(d, a, b, c, x[k + 11], S42, 0xBD3AF235);
  193. c = _II(c, d, a, b, x[k + 2], S43, 0x2AD7D2BB);
  194. b = _II(b, c, d, a, x[k + 9], S44, 0xEB86D391);
  195. a = addUnsigned(a, AA);
  196. b = addUnsigned(b, BB);
  197. c = addUnsigned(c, CC);
  198. d = addUnsigned(d, DD);
  199. }
  200. var temp = wordToHex(a) + wordToHex(b) + wordToHex(c) + wordToHex(d);
  201. return temp.toLowerCase();
  202. }
  203. //-----------------------------------------------------------------
  204. //-----------------------------------------------------------------
  205. function uniqid (prefix, more_entropy) {
  206. // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  207. // + revised by: Kankrelune (http://www.webfaktory.info/)
  208. // % note 1: Uses an internal counter (in php_js global) to avoid collision
  209. // * example 1: uniqid();
  210. // * returns 1: 'a30285b160c14'
  211. // * example 2: uniqid('foo');
  212. // * returns 2: 'fooa30285b1cd361'
  213. // * example 3: uniqid('bar', true);
  214. // * returns 3: 'bara20285b23dfd1.31879087'
  215. if (typeof prefix == 'undefined') {
  216. prefix = "";
  217. }
  218. var retId;
  219. var formatSeed = function (seed, reqWidth) {
  220. seed = parseInt(seed, 10).toString(16); // to hex str
  221. if (reqWidth < seed.length) { // so long we split
  222. return seed.slice(seed.length - reqWidth);
  223. }
  224. if (reqWidth > seed.length) { // so short we pad
  225. return Array(1 + (reqWidth - seed.length)).join('0') + seed;
  226. }
  227. return seed;
  228. };
  229. // BEGIN REDUNDANT
  230. if (!this.php_js) {
  231. this.php_js = {};
  232. }
  233. // END REDUNDANT
  234. if (!this.php_js.uniqidSeed) { // init seed with big random int
  235. this.php_js.uniqidSeed = Math.floor(Math.random() * 0x75bcd15);
  236. }
  237. this.php_js.uniqidSeed++;
  238. retId = prefix; // start with prefix, add current milliseconds hex string
  239. retId += formatSeed(parseInt(new Date().getTime() / 1000, 10), 8);
  240. retId += formatSeed(this.php_js.uniqidSeed, 5); // add seed hex string
  241. if (more_entropy) {
  242. // for more entropy we add a float lower to 10
  243. retId += (Math.random() * 10).toFixed(8).toString();
  244. }
  245. return retId;
  246. }
  247. /*
  248. 字串->陣列 by 分隔符號
  249. */
  250. function explode(delimiter, data_array){
  251. var exploded = data_array.split(delimiter);
  252. //the delimiter was not found if the second array returns undefined
  253. if(exploded[1]===undefined){
  254. // alert("delimiter " + delimiter + " was not found");
  255. //you can return false here
  256. return false;
  257. }
  258. else{
  259. // alert(exploded);
  260. return exploded;
  261. //you can return true or return the exploded value here
  262. }
  263. }
  264. /*
  265. 陣列->字串 by 分隔符號
  266. */
  267. function implode(glue, pieces) {
  268. var i = '',
  269. retVal = '',
  270. tGlue = '';
  271. if (arguments.length === 1) {
  272. pieces = glue;
  273. glue = '';
  274. }
  275. if (typeof(pieces) === 'object') {
  276. if (Object.prototype.toString.call(pieces) === '[object Array]') {
  277. return pieces.join(glue);
  278. }
  279. for (i in pieces) {
  280. retVal += tGlue + pieces[i];
  281. tGlue = glue;
  282. }
  283. return retVal;
  284. }
  285. return pieces;
  286. }
  287. /*
  288. 浮點數
  289. */
  290. //浮點數相加
  291. function bcadd(left_operand, right_operand, scale) {
  292. // discuss at: http://phpjs.org/functions/bcadd/
  293. // original by: lmeyrick (https://sourceforge.net/projects/bcmath-js/)
  294. // depends on: _phpjs_shared_bc
  295. // example 1: bcadd(1, 2);
  296. // returns 1: 3
  297. // todo: implement these testcases
  298. var libbcmath = this._phpjs_shared_bc();
  299. var first, second, result;
  300. if (typeof scale === 'undefined') {
  301. scale = libbcmath.scale;
  302. }
  303. scale = ((scale < 0) ? 0 : scale);
  304. // create objects
  305. first = libbcmath.bc_init_num();
  306. second = libbcmath.bc_init_num();
  307. result = libbcmath.bc_init_num();
  308. first = libbcmath.php_str2num(left_operand.toString());
  309. second = libbcmath.php_str2num(right_operand.toString());
  310. result = libbcmath.bc_add(first, second, scale);
  311. if (result.n_scale > scale) {
  312. result.n_scale = scale;
  313. }
  314. return result.toString();
  315. }
  316. //浮點數相減
  317. function bcsub(left_operand, right_operand, scale) {
  318. // discuss at: http://phpjs.org/functions/bcsub/
  319. // original by: lmeyrick (https://sourceforge.net/projects/bcmath-js/)
  320. // depends on: _phpjs_shared_bc
  321. // example 1: bcsub(1, 2);
  322. // returns 1: -1
  323. // todo: implement these testcases
  324. var libbcmath = this._phpjs_shared_bc();
  325. var first, second, result;
  326. if (typeof scale === 'undefined') {
  327. scale = libbcmath.scale;
  328. }
  329. scale = ((scale < 0) ? 0 : scale);
  330. // create objects
  331. first = libbcmath.bc_init_num();
  332. second = libbcmath.bc_init_num();
  333. result = libbcmath.bc_init_num();
  334. first = libbcmath.php_str2num(left_operand.toString());
  335. second = libbcmath.php_str2num(right_operand.toString());
  336. result = libbcmath.bc_sub(first, second, scale);
  337. if (result.n_scale > scale) {
  338. result.n_scale = scale;
  339. }
  340. return result.toString();
  341. }
  342. //浮點數相乘
  343. function bcmul(left_operand, right_operand, scale) {
  344. // discuss at: http://phpjs.org/functions/bcmul/
  345. // original by: lmeyrick (https://sourceforge.net/projects/bcmath-js/)
  346. // depends on: _phpjs_shared_bc
  347. // example 1: bcmul(1, 2);
  348. // returns 1: 3
  349. // todo: implement these testcases
  350. var libbcmath = this._phpjs_shared_bc();
  351. var first, second, result;
  352. if (typeof scale === 'undefined') {
  353. scale = libbcmath.scale;
  354. }
  355. scale = ((scale < 0) ? 0 : scale);
  356. // create objects
  357. first = libbcmath.bc_init_num();
  358. second = libbcmath.bc_init_num();
  359. result = libbcmath.bc_init_num();
  360. first = libbcmath.php_str2num(left_operand.toString());
  361. second = libbcmath.php_str2num(right_operand.toString());
  362. result = libbcmath.bc_multiply(first, second, scale);
  363. if (result.n_scale > scale) {
  364. result.n_scale = scale;
  365. }
  366. return result.toString();
  367. }
  368. /*
  369. 浮點數相除
  370. */
  371. function bcdiv(left_operand, right_operand, scale) {
  372. // discuss at: http://phpjs.org/functions/bcdiv/
  373. // original by: lmeyrick (https://sourceforge.net/projects/bcmath-js/)
  374. // depends on: _phpjs_shared_bc
  375. // example 1: bcdiv(1, 2);
  376. // returns 1: 3
  377. // todo: implement these testcases
  378. var libbcmath = this._phpjs_shared_bc();
  379. var first, second, result;
  380. if (typeof scale === 'undefined') {
  381. scale = libbcmath.scale;
  382. }
  383. scale = ((scale < 0) ? 0 : scale);
  384. // create objects
  385. first = libbcmath.bc_init_num();
  386. second = libbcmath.bc_init_num();
  387. result = libbcmath.bc_init_num();
  388. first = libbcmath.php_str2num(left_operand.toString());
  389. second = libbcmath.php_str2num(right_operand.toString());
  390. result = libbcmath.bc_divide(first, second, scale);
  391. if (result === -1) {
  392. // error
  393. // throw new Error(11, '(BC) Division by zero');
  394. }
  395. if (result.n_scale > scale) {
  396. result.n_scale = scale;
  397. }
  398. return result.toString();
  399. }
  400. /*
  401. */
  402. function bccomp(left_operand, right_operand, scale) {
  403. // discuss at: http://phpjs.org/functions/bccomp/
  404. // original by: lmeyrick (https://sourceforge.net/projects/bcmath-js/)
  405. // depends on: _phpjs_shared_bc
  406. // example 1: bccomp(1, 2);
  407. // returns 1: 3
  408. // todo: implement these testcases
  409. var libbcmath = this._phpjs_shared_bc();
  410. var first, second; //bc_num
  411. if (typeof scale === 'undefined') {
  412. scale = libbcmath.scale;
  413. }
  414. scale = ((scale < 0) ? 0 : scale);
  415. first = libbcmath.bc_init_num();
  416. second = libbcmath.bc_init_num();
  417. first = libbcmath.bc_str2num(left_operand.toString(), scale); // note bc_ not php_str2num
  418. second = libbcmath.bc_str2num(right_operand.toString(), scale); // note bc_ not php_str2num
  419. return libbcmath.bc_compare(first, second, scale);
  420. }
  421. function bcround(val, precision) {
  422. // discuss at: http://phpjs.org/functions/bcround/
  423. // original by: lmeyrick (https://sourceforge.net/projects/bcmath-js/)
  424. // depends on: _phpjs_shared_bc
  425. // example 1: bcround(1, 2);
  426. // returns 1: 3
  427. // todo: implement these testcases
  428. var libbcmath = this._phpjs_shared_bc();
  429. var temp, result, digit;
  430. var right_operand;
  431. // create number
  432. temp = libbcmath.bc_init_num();
  433. temp = libbcmath.php_str2num(val.toString());
  434. // check if any rounding needs
  435. if (precision >= temp.n_scale) {
  436. // nothing to round, just add the zeros.
  437. while (temp.n_scale < precision) {
  438. temp.n_value[temp.n_len + temp.n_scale] = 0;
  439. temp.n_scale++;
  440. }
  441. return temp.toString();
  442. }
  443. // get the digit we are checking (1 after the precision)
  444. // loop through digits after the precision marker
  445. digit = temp.n_value[temp.n_len + precision];
  446. right_operand = libbcmath.bc_init_num();
  447. right_operand = libbcmath.bc_new_num(1, precision);
  448. if (digit >= 5) {
  449. //round away from zero by adding 1 (or -1) at the "precision".. ie 1.44999 @ 3dp = (1.44999 + 0.001).toString().substr(0,5)
  450. right_operand.n_value[right_operand.n_len + right_operand.n_scale - 1] = 1;
  451. if (temp.n_sign == libbcmath.MINUS) {
  452. // round down
  453. right_operand.n_sign = libbcmath.MINUS;
  454. }
  455. result = libbcmath.bc_add(temp, right_operand, precision);
  456. } else {
  457. // leave-as-is.. just truncate it.
  458. result = temp;
  459. }
  460. if (result.n_scale > precision) {
  461. result.n_scale = precision;
  462. }
  463. return result.toString();
  464. }
  465. function bcscale(scale) {
  466. // discuss at: http://phpjs.org/functions/bcscale/
  467. // original by: lmeyrick (https://sourceforge.net/projects/bcmath-js/)this.
  468. // depends on: _phpjs_shared_bc
  469. // example 1: bcscale(1);
  470. // returns 1: 3
  471. // todo: implement these testcases
  472. var libbcmath = this._phpjs_shared_bc();
  473. scale = parseInt(scale, 10);
  474. if (isNaN(scale)) {
  475. return false;
  476. }
  477. if (scale < 0) {
  478. return false;
  479. }
  480. libbcmath.scale = scale;
  481. return true;
  482. }
  483. /*
  484. 判斷值
  485. */
  486. function isset() {
  487. // !No description available for isset. @php.js developers: Please update the function summary text file.
  488. //
  489. // version: 1103.1210
  490. // discuss at: http://phpjs.org/functions/isset
  491. // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  492. // + improved by: FremyCompany
  493. // + improved by: Onno Marsman
  494. // + improved by: Rafał Kukawski
  495. // * example 1: isset( undefined, true);
  496. // * returns 1: false
  497. // * example 2: isset( 'Kevin van Zonneveld' );
  498. // * returns 2: true
  499. var a = arguments,
  500. l = a.length,
  501. i = 0,
  502. undef;
  503. if (l === 0) {
  504. throw new Error('Empty isset');
  505. }
  506. while (i !== l) {
  507. if (a[i] === undef || a[i] === null) {
  508. return false;
  509. }
  510. i++;
  511. }
  512. return true;
  513. }
  514. function empty(mixed_var) {
  515. // discuss at: http://phpjs.org/functions/empty/
  516. // original by: Philippe Baumann
  517. // input by: Onno Marsman
  518. // input by: LH
  519. // input by: Stoyan Kyosev (http://www.svest.org/)
  520. // bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  521. // improved by: Onno Marsman
  522. // improved by: Francesco
  523. // improved by: Marc Jansen
  524. // improved by: Rafal Kukawski
  525. // example 1: empty(null);
  526. // returns 1: true
  527. // example 2: empty(undefined);
  528. // returns 2: true
  529. // example 3: empty([]);
  530. // returns 3: true
  531. // example 4: empty({});
  532. // returns 4: true
  533. // example 5: empty({'aFunc' : function () { alert('humpty'); } });
  534. // returns 5: false
  535. var undef, key, i, len;
  536. var emptyValues = [undef, null, false, 0, '', '0'];
  537. for (i = 0, len = emptyValues.length; i < len; i++) {
  538. if (mixed_var === emptyValues[i]) {
  539. return true;
  540. }
  541. }
  542. if (typeof mixed_var === 'object') {
  543. for (key in mixed_var) {
  544. // TODO: should we check for own properties only?
  545. //if (mixed_var.hasOwnProperty(key)) {
  546. return false;
  547. //}
  548. }
  549. return true;
  550. }
  551. return false;
  552. }
  553. //-----------------------------------------------------------------
  554. //-----------------------------------------------------------------
  555. //-----------------------------------------------------------------
  556. //-----------------------------------------------------------------
  557. //-----------------------------------------------------------------
  558. //-----------------------------------------------------------------
  559. //-----------------------------------------------------------------
  560. //-----------------------------------------------------------------
  561. //-----------------------------------------------------------------
  562. //-----------------------------------------------------------------
  563. //-----------------------------------------------------------------
  564. //-----------------------------------------------------------------
  565. //-----------------------------------------------------------------
  566. function _phpjs_shared_bc() {
  567. // From: http://phpjs.org/functions
  568. // + original by: lmeyrick (https://sourceforge.net/projects/bcmath-js/)
  569. // + improved by: Brett Zamir (http://brett-zamir.me)
  570. // * example 1: _phpjs_shared_bc();
  571. // * returns 1: {}
  572. /**
  573. * BC Math Library for Javascript
  574. * Ported from the PHP5 bcmath extension source code,
  575. * which uses the libbcmath package...
  576. * Copyright (C) 1991, 1992, 1993, 1994, 1997 Free Software Foundation, Inc.
  577. * Copyright (C) 2000 Philip A. Nelson
  578. * The Free Software Foundation, Inc.
  579. * 59 Temple Place, Suite 330
  580. * Boston, MA 02111-1307 USA.
  581. * e-mail: philnelson@acm.org
  582. * us-mail: Philip A. Nelson
  583. * Computer Science Department, 9062
  584. * Western Washington University
  585. * Bellingham, WA 98226-9062
  586. *
  587. * bcmath-js homepage:
  588. *
  589. * This code is covered under the LGPL licence, and can be used however you want :)
  590. * Be kind and share any decent code changes.
  591. */
  592. /**
  593. * Binary Calculator (BC) Arbitrary Precision Mathematics Lib v0.10 (LGPL)
  594. * Copy of libbcmath included in PHP5 src
  595. *
  596. * Note: this is just the shared library file and does not include the php-style functions.
  597. * use bcmath{-min}.js for functions like bcadd, bcsub etc.
  598. *
  599. * Feel free to use how-ever you want, just email any bug-fixes/improvements to the sourceforge project:
  600. *
  601. *
  602. * Ported from the PHP5 bcmath extension source code,
  603. * which uses the libbcmath package...
  604. * Copyright (C) 1991, 1992, 1993, 1994, 1997 Free Software Foundation, Inc.
  605. * Copyright (C) 2000 Philip A. Nelson
  606. * The Free Software Foundation, Inc.
  607. * 59 Temple Place, Suite 330
  608. * Boston, MA 02111-1307 USA.
  609. * e-mail: philnelson@acm.org
  610. * us-mail: Philip A. Nelson
  611. * Computer Science Department, 9062
  612. * Western Washington University
  613. * Bellingham, WA 98226-9062
  614. */
  615. var libbcmath = {
  616. PLUS: '+',
  617. MINUS: '-',
  618. BASE: 10,
  619. // must be 10 (for now)
  620. scale: 0,
  621. // default scale
  622. /**
  623. * Basic number structure
  624. */
  625. bc_num: function() {
  626. this.n_sign = null; // sign
  627. this.n_len = null; /* (int) The number of digits before the decimal point. */
  628. this.n_scale = null; /* (int) The number of digits after the decimal point. */
  629. //this.n_refs = null; /* (int) The number of pointers to this number. */
  630. //this.n_text = null; /* ?? Linked list for available list. */
  631. this.n_value = null; /* array as value, where 1.23 = [1,2,3] */
  632. this.toString = function() {
  633. var r, tmp;
  634. tmp = this.n_value.join('');
  635. // add minus sign (if applicable) then add the integer part
  636. r = ((this.n_sign == libbcmath.PLUS) ? '' : this.n_sign) + tmp.substr(0, this.n_len);
  637. // if decimal places, add a . and the decimal part
  638. if (this.n_scale > 0) {
  639. r += '.' + tmp.substr(this.n_len, this.n_scale);
  640. }
  641. return r;
  642. };
  643. },
  644. /**
  645. * Base add function
  646. *
  647. // Here is the full add routine that takes care of negative numbers.
  648. // N1 is added to N2 and the result placed into RESULT. SCALE_MIN
  649. // is the minimum scale for the result.
  650. *
  651. * @param {bc_num} n1
  652. * @param {bc_num} n2
  653. * @param {int} scale_min
  654. * @return bc_num
  655. */
  656. bc_add: function(n1, n2, scale_min) {
  657. var sum, cmp_res, res_scale;
  658. if (n1.n_sign === n2.n_sign) {
  659. sum = libbcmath._bc_do_add(n1, n2, scale_min);
  660. sum.n_sign = n1.n_sign;
  661. } else { /* subtraction must be done. */
  662. cmp_res = libbcmath._bc_do_compare(n1, n2, false, false); /* Compare magnitudes. */
  663. switch (cmp_res) {
  664. case -1:
  665. /* n1 is less than n2, subtract n1 from n2. */
  666. sum = libbcmath._bc_do_sub(n2, n1, scale_min);
  667. sum.n_sign = n2.n_sign;
  668. break;
  669. case 0:
  670. /* They are equal! return zero with the correct scale! */
  671. res_scale = libbcmath.MAX(scale_min, libbcmath.MAX(n1.n_scale, n2.n_scale));
  672. sum = libbcmath.bc_new_num(1, res_scale);
  673. libbcmath.memset(sum.n_value, 0, 0, res_scale + 1);
  674. break;
  675. case 1:
  676. /* n2 is less than n1, subtract n2 from n1. */
  677. sum = libbcmath._bc_do_sub(n1, n2, scale_min);
  678. sum.n_sign = n1.n_sign;
  679. }
  680. }
  681. return sum;
  682. },
  683. /**
  684. * This is the "user callable" routine to compare numbers N1 and N2.
  685. * @param {bc_num} n1
  686. * @param {bc_num} n2
  687. * @return int -1, 0, 1 (n1 < n2, ==, n1 > n2)
  688. */
  689. bc_compare: function(n1, n2) {
  690. return libbcmath._bc_do_compare(n1, n2, true, false);
  691. },
  692. _one_mult: function(num, n_ptr, size, digit, result, r_ptr) {
  693. var carry, value; // int
  694. var nptr, rptr; // int pointers
  695. if (digit === 0) {
  696. libbcmath.memset(result, 0, 0, size); //memset (result, 0, size);
  697. } else {
  698. if (digit == 1) {
  699. libbcmath.memcpy(result, r_ptr, num, n_ptr, size); //memcpy (result, num, size);
  700. } else { /* Initialize */
  701. nptr = n_ptr + size - 1; //nptr = (unsigned char *) (num+size-1);
  702. rptr = r_ptr + size - 1; //rptr = (unsigned char *) (result+size-1);
  703. carry = 0;
  704. while (size-- > 0) {
  705. value = num[nptr--] * digit + carry; //value = *nptr-- * digit + carry;
  706. //result[rptr--] = libbcmath.cint(value % libbcmath.BASE); // @CHECK cint //*rptr-- = value % BASE;
  707. result[rptr--] = value % libbcmath.BASE; // @CHECK cint //*rptr-- = value % BASE;
  708. //carry = libbcmath.cint(value / libbcmath.BASE); // @CHECK cint //carry = value / BASE;
  709. carry = Math.floor(value / libbcmath.BASE); // @CHECK cint //carry = value / BASE;
  710. }
  711. if (carry !== 0) {
  712. result[rptr] = carry;
  713. }
  714. }
  715. }
  716. },
  717. bc_divide: function(n1, n2, scale) {
  718. var quot; // bc_num return
  719. var qval; // bc_num
  720. var num1, num2; // string
  721. var ptr1, ptr2, n2ptr, qptr; // int pointers
  722. var scale1, val; // int
  723. var len1, len2, scale2, qdigits, extra, count; // int
  724. var qdig, qguess, borrow, carry; // int
  725. var mval; // string
  726. var zero; // char
  727. var norm; // int
  728. var ptrs; // return object from one_mul
  729. /* Test for divide by zero. (return failure) */
  730. if (libbcmath.bc_is_zero(n2)) {
  731. return -1;
  732. }
  733. /* Test for zero divide by anything (return zero) */
  734. if (libbcmath.bc_is_zero(n1)) {
  735. return libbcmath.bc_new_num(1, scale);
  736. }
  737. /* Test for n1 equals n2 (return 1 as n1 nor n2 are zero)
  738. if (libbcmath.bc_compare(n1, n2, libbcmath.MAX(n1.n_scale, n2.n_scale)) === 0) {
  739. quot=libbcmath.bc_new_num(1, scale);
  740. quot.n_value[0] = 1;
  741. return quot;
  742. }
  743. */
  744. /* Test for divide by 1. If it is we must truncate. */
  745. // todo: check where scale > 0 too.. can't see why not (ie bc_is_zero - add bc_is_one function)
  746. if (n2.n_scale === 0) {
  747. if (n2.n_len === 1 && n2.n_value[0] === 1) {
  748. qval = libbcmath.bc_new_num(n1.n_len, scale); //qval = bc_new_num (n1->n_len, scale);
  749. qval.n_sign = (n1.n_sign == n2.n_sign ? libbcmath.PLUS : libbcmath.MINUS);
  750. libbcmath.memset(qval.n_value, n1.n_len, 0, scale); //memset (&qval->n_value[n1->n_len],0,scale);
  751. libbcmath.memcpy(qval.n_value, 0, n1.n_value, 0, n1.n_len + libbcmath.MIN(n1.n_scale, scale)); //memcpy (qval->n_value, n1->n_value, n1->n_len + MIN(n1->n_scale,scale));
  752. // can we return here? not in c src, but can't see why-not.
  753. // return qval;
  754. }
  755. }
  756. /* Set up the divide. Move the decimal point on n1 by n2's scale.
  757. Remember, zeros on the end of num2 are wasted effort for dividing. */
  758. scale2 = n2.n_scale; //scale2 = n2->n_scale;
  759. n2ptr = n2.n_len + scale2 - 1; //n2ptr = (unsigned char *) n2.n_value+n2.n_len+scale2-1;
  760. while ((scale2 > 0) && (n2.n_value[n2ptr--] === 0)) {
  761. scale2--;
  762. }
  763. len1 = n1.n_len + scale2;
  764. scale1 = n1.n_scale - scale2;
  765. if (scale1 < scale) {
  766. extra = scale - scale1;
  767. } else {
  768. extra = 0;
  769. }
  770. num1 = libbcmath.safe_emalloc(1, n1.n_len + n1.n_scale, extra + 2); //num1 = (unsigned char *) safe_emalloc (1, n1.n_len+n1.n_scale, extra+2);
  771. if (num1 === null) {
  772. libbcmath.bc_out_of_memory();
  773. }
  774. libbcmath.memset(num1, 0, 0, n1.n_len + n1.n_scale + extra + 2); //memset (num1, 0, n1->n_len+n1->n_scale+extra+2);
  775. libbcmath.memcpy(num1, 1, n1.n_value, 0, n1.n_len + n1.n_scale); //memcpy (num1+1, n1.n_value, n1.n_len+n1.n_scale);
  776. len2 = n2.n_len + scale2; // len2 = n2->n_len + scale2;
  777. num2 = libbcmath.safe_emalloc(1, len2, 1); //num2 = (unsigned char *) safe_emalloc (1, len2, 1);
  778. if (num2 === null) {
  779. libbcmath.bc_out_of_memory();
  780. }
  781. libbcmath.memcpy(num2, 0, n2.n_value, 0, len2); //memcpy (num2, n2.n_value, len2);
  782. num2[len2] = 0; // *(num2+len2) = 0;
  783. n2ptr = 0; //n2ptr = num2;
  784. while (num2[n2ptr] === 0) { // while (*n2ptr == 0)
  785. n2ptr++;
  786. len2--;
  787. }
  788. /* Calculate the number of quotient digits. */
  789. if (len2 > len1 + scale) {
  790. qdigits = scale + 1;
  791. zero = true;
  792. } else {
  793. zero = false;
  794. if (len2 > len1) {
  795. qdigits = scale + 1; /* One for the zero integer part. */
  796. } else {
  797. qdigits = len1 - len2 + scale + 1;
  798. }
  799. }
  800. /* Allocate and zero the storage for the quotient. */
  801. qval = libbcmath.bc_new_num(qdigits - scale, scale); //qval = bc_new_num (qdigits-scale,scale);
  802. libbcmath.memset(qval.n_value, 0, 0, qdigits); //memset (qval->n_value, 0, qdigits);
  803. /* Allocate storage for the temporary storage mval. */
  804. mval = libbcmath.safe_emalloc(1, len2, 1); //mval = (unsigned char *) safe_emalloc (1, len2, 1);
  805. if (mval === null) {
  806. libbcmath.bc_out_of_memory();
  807. }
  808. /* Now for the full divide algorithm. */
  809. if (!zero) { /* Normalize */
  810. //norm = libbcmath.cint(10 / (libbcmath.cint(n2.n_value[n2ptr]) + 1)); //norm = 10 / ((int)*n2ptr + 1);
  811. norm = Math.floor(10 / (n2.n_value[n2ptr] + 1)); //norm = 10 / ((int)*n2ptr + 1);
  812. if (norm != 1) {
  813. libbcmath._one_mult(num1, 0, len1 + scale1 + extra + 1, norm, num1, 0); //libbcmath._one_mult(num1, len1+scale1+extra+1, norm, num1);
  814. libbcmath._one_mult(n2.n_value, n2ptr, len2, norm, n2.n_value, n2ptr); //libbcmath._one_mult(n2ptr, len2, norm, n2ptr);
  815. // @CHECK Is the pointer affected by the call? if so, maybe need to adjust points on return?
  816. }
  817. /* Initialize divide loop. */
  818. qdig = 0;
  819. if (len2 > len1) {
  820. qptr = len2 - len1; //qptr = (unsigned char *) qval.n_value+len2-len1;
  821. } else {
  822. qptr = 0; //qptr = (unsigned char *) qval.n_value;
  823. }
  824. /* Loop */
  825. while (qdig <= len1 + scale - len2) { /* Calculate the quotient digit guess. */
  826. if (n2.n_value[n2ptr] == num1[qdig]) {
  827. qguess = 9;
  828. } else {
  829. qguess = Math.floor((num1[qdig] * 10 + num1[qdig + 1]) / n2.n_value[n2ptr]);
  830. } /* Test qguess. */
  831. if (n2.n_value[n2ptr + 1] * qguess > (num1[qdig] * 10 + num1[qdig + 1] - n2.n_value[n2ptr] * qguess) * 10 + num1[qdig + 2]) { //if (n2ptr[1]*qguess > (num1[qdig]*10 + num1[qdig+1] - *n2ptr*qguess)*10 + num1[qdig+2]) {
  832. qguess--; /* And again. */
  833. if (n2.n_value[n2ptr + 1] * qguess > (num1[qdig] * 10 + num1[qdig + 1] - n2.n_value[n2ptr] * qguess) * 10 + num1[qdig + 2]) { //if (n2ptr[1]*qguess > (num1[qdig]*10 + num1[qdig+1] - *n2ptr*qguess)*10 + num1[qdig+2])
  834. qguess--;
  835. }
  836. }
  837. /* Multiply and subtract. */
  838. borrow = 0;
  839. if (qguess !== 0) {
  840. mval[0] = 0; //*mval = 0; // @CHECK is this to fix ptr2 < 0?
  841. libbcmath._one_mult(n2.n_value, n2ptr, len2, qguess, mval, 1); //_one_mult (n2ptr, len2, qguess, mval+1); // @CHECK
  842. ptr1 = qdig + len2; //(unsigned char *) num1+qdig+len2;
  843. ptr2 = len2; //(unsigned char *) mval+len2;
  844. // @CHECK: Does a negative pointer return null?
  845. // ptr2 can be < 0 here as ptr1 = len2, thus count < len2+1 will always fail ?
  846. for (count = 0; count < len2 + 1; count++) {
  847. if (ptr2 < 0) {
  848. //val = libbcmath.cint(num1[ptr1]) - 0 - borrow; //val = (int) *ptr1 - (int) *ptr2-- - borrow;
  849. val = num1[ptr1] - 0 - borrow; //val = (int) *ptr1 - (int) *ptr2-- - borrow;
  850. } else {
  851. //val = libbcmath.cint(num1[ptr1]) - libbcmath.cint(mval[ptr2--]) - borrow; //val = (int) *ptr1 - (int) *ptr2-- - borrow;
  852. val = num1[ptr1] - mval[ptr2--] - borrow; //val = (int) *ptr1 - (int) *ptr2-- - borrow;
  853. }
  854. if (val < 0) {
  855. val += 10;
  856. borrow = 1;
  857. } else {
  858. borrow = 0;
  859. }
  860. num1[ptr1--] = val;
  861. }
  862. }
  863. /* Test for negative result. */
  864. if (borrow == 1) {
  865. qguess--;
  866. ptr1 = qdig + len2; //(unsigned char *) num1+qdig+len2;
  867. ptr2 = len2 - 1; //(unsigned char *) n2ptr+len2-1;
  868. carry = 0;
  869. for (count = 0; count < len2; count++) {
  870. if (ptr2 < 0) {
  871. //val = libbcmath.cint(num1[ptr1]) + 0 + carry; //val = (int) *ptr1 + (int) *ptr2-- + carry;
  872. val = num1[ptr1] + 0 + carry; //val = (int) *ptr1 + (int) *ptr2-- + carry;
  873. } else {
  874. //val = libbcmath.cint(num1[ptr1]) + libbcmath.cint(n2.n_value[ptr2--]) + carry; //val = (int) *ptr1 + (int) *ptr2-- + carry;
  875. val = num1[ptr1] + n2.n_value[ptr2--] + carry; //val = (int) *ptr1 + (int) *ptr2-- + carry;
  876. }
  877. if (val > 9) {
  878. val -= 10;
  879. carry = 1;
  880. } else {
  881. carry = 0;
  882. }
  883. num1[ptr1--] = val; //*ptr1-- = val;
  884. }
  885. if (carry == 1) {
  886. //num1[ptr1] = libbcmath.cint((num1[ptr1] + 1) % 10); // *ptr1 = (*ptr1 + 1) % 10; // @CHECK
  887. num1[ptr1] = (num1[ptr1] + 1) % 10; // *ptr1 = (*ptr1 + 1) % 10; // @CHECK
  888. }
  889. }
  890. /* We now know the quotient digit. */
  891. qval.n_value[qptr++] = qguess; //*qptr++ = qguess;
  892. qdig++;
  893. }
  894. }
  895. /* Clean up and return the number. */
  896. qval.n_sign = (n1.n_sign == n2.n_sign ? libbcmath.PLUS : libbcmath.MINUS);
  897. if (libbcmath.bc_is_zero(qval)) {
  898. qval.n_sign = libbcmath.PLUS;
  899. }
  900. libbcmath._bc_rm_leading_zeros(qval);
  901. return qval;
  902. //return 0; /* Everything is OK. */
  903. },
  904. MUL_BASE_DIGITS: 80,
  905. MUL_SMALL_DIGITS: (this.MUL_BASE_DIGITS / 4),
  906. //#define MUL_SMALL_DIGITS mul_base_digits/4
  907. /* The multiply routine. N2 times N1 is put int PROD with the scale of
  908. the result being MIN(N2 scale+N1 scale, MAX (SCALE, N2 scale, N1 scale)).
  909. */
  910. /**
  911. * @param n1 bc_num
  912. * @param n2 bc_num
  913. * @param scale [int] optional
  914. */
  915. bc_multiply: function(n1, n2, scale) {
  916. var pval; // bc_num
  917. var len1, len2; // int
  918. var full_scale, prod_scale; // int
  919. // Initialize things.
  920. len1 = n1.n_len + n1.n_scale;
  921. len2 = n2.n_len + n2.n_scale;
  922. full_scale = n1.n_scale + n2.n_scale;
  923. prod_scale = libbcmath.MIN(full_scale, libbcmath.MAX(scale, libbcmath.MAX(n1.n_scale, n2.n_scale)));
  924. //pval = libbcmath.bc_init_num(); // allow pass by ref
  925. // Do the multiply
  926. pval = libbcmath._bc_rec_mul(n1, len1, n2, len2, full_scale);
  927. // Assign to prod and clean up the number.
  928. pval.n_sign = (n1.n_sign == n2.n_sign ? libbcmath.PLUS : libbcmath.MINUS);
  929. //pval.n_value = pval.n_ptr; // @FIX
  930. pval.n_len = len2 + len1 + 1 - full_scale;
  931. pval.n_scale = prod_scale;
  932. libbcmath._bc_rm_leading_zeros(pval);
  933. if (libbcmath.bc_is_zero(pval)) {
  934. pval.n_sign = libbcmath.PLUS;
  935. }
  936. //bc_free_num (prod);
  937. return pval;
  938. },
  939. new_sub_num: function(length, scale, value) {
  940. var temp = new libbcmath.bc_num();
  941. temp.n_sign = libbcmath.PLUS;
  942. temp.n_len = length;
  943. temp.n_scale = scale;
  944. temp.n_value = value;
  945. return temp;
  946. },
  947. _bc_simp_mul: function(n1, n1len, n2, n2len, full_scale) {
  948. var prod; // bc_num
  949. var n1ptr, n2ptr, pvptr; // char *n1ptr, *n2ptr, *pvptr;
  950. var n1end, n2end; //char *n1end, *n2end; /* To the end of n1 and n2. */
  951. var indx, sum, prodlen; //int indx, sum, prodlen;
  952. prodlen = n1len + n2len + 1;
  953. prod = libbcmath.bc_new_num(prodlen, 0);
  954. n1end = n1len - 1; //(char *) (n1->n_value + n1len - 1);
  955. n2end = n2len - 1; //(char *) (n2->n_value + n2len - 1);
  956. pvptr = prodlen - 1; //(char *) ((*prod)->n_value + prodlen - 1);
  957. sum = 0;
  958. // Here is the loop...
  959. for (indx = 0; indx < prodlen - 1; indx++) {
  960. n1ptr = n1end - libbcmath.MAX(0, indx - n2len + 1); //(char *) (n1end - MAX(0, indx-n2len+1));
  961. n2ptr = n2end - libbcmath.MIN(indx, n2len - 1); //(char *) (n2end - MIN(indx, n2len-1));
  962. while ((n1ptr >= 0) && (n2ptr <= n2end)) {
  963. sum += n1.n_value[n1ptr--] * n2.n_value[n2ptr++]; //sum += *n1ptr-- * *n2ptr++;
  964. }
  965. prod.n_value[pvptr--] = Math.floor(sum % libbcmath.BASE); //*pvptr-- = sum % BASE;
  966. sum = Math.floor(sum / libbcmath.BASE); //sum = sum / BASE;
  967. }
  968. prod.n_value[pvptr] = sum; //*pvptr = sum;
  969. return prod;
  970. },
  971. /* A special adder/subtractor for the recursive divide and conquer
  972. multiply algorithm. Note: if sub is called, accum must
  973. be larger that what is being subtracted. Also, accum and val
  974. must have n_scale = 0. (e.g. they must look like integers. *) */
  975. _bc_shift_addsub: function(accum, val, shift, sub) {
  976. var accp, valp; //signed char *accp, *valp;
  977. var count, carry; //int count, carry;
  978. count = val.n_len;
  979. if (val.n_value[0] === 0) {
  980. count--;
  981. }
  982. //assert (accum->n_len+accum->n_scale >= shift+count);
  983. if (accum.n_len + accum.n_scale < shift + count) {
  984. throw new Error('len + scale < shift + count'); // ?? I think that's what assert does :)
  985. }
  986. // Set up pointers and others
  987. accp = accum.n_len + accum.n_scale - shift - 1; // (signed char *)(accum->n_value + accum->n_len + accum->n_scale - shift - 1);
  988. valp = val.n_len = 1; //(signed char *)(val->n_value + val->n_len - 1);
  989. carry = 0;
  990. if (sub) {
  991. // Subtraction, carry is really borrow.
  992. while (count--) {
  993. accum.n_value[accp] -= val.n_value[valp--] + carry; //*accp -= *valp-- + carry;
  994. if (accum.n_value[accp] < 0) { //if (*accp < 0)
  995. carry = 1;
  996. accum.n_value[accp--] += libbcmath.BASE; //*accp-- += BASE;
  997. } else {
  998. carry = 0;
  999. accp--;
  1000. }
  1001. }
  1002. while (carry) {
  1003. accum.n_value[accp] -= carry; //*accp -= carry;
  1004. if (accum.n_value[accp] < 0) { //if (*accp < 0)
  1005. accum.n_value[accp--] += libbcmath.BASE; // *accp-- += BASE;
  1006. } else {
  1007. carry = 0;
  1008. }
  1009. }
  1010. } else {
  1011. // Addition
  1012. while (count--) {
  1013. accum.n_value[accp] += val.n_value[valp--] + carry; //*accp += *valp-- + carry;
  1014. if (accum.n_value[accp] > (libbcmath.BASE - 1)) { //if (*accp > (BASE-1))
  1015. carry = 1;
  1016. accum.n_value[accp--] -= libbcmath.BASE; //*accp-- -= BASE;
  1017. } else {
  1018. carry = 0;
  1019. accp--;
  1020. }
  1021. }
  1022. while (carry) {
  1023. accum.n_value[accp] += carry; //*accp += carry;
  1024. if (accum.n_value[accp] > (libbcmath.BASE - 1)) { //if (*accp > (BASE-1))
  1025. accum.n_value[accp--] -= libbcmath.BASE; //*accp-- -= BASE;
  1026. } else {
  1027. carry = 0;
  1028. }
  1029. }
  1030. }
  1031. return true; // accum is the pass-by-reference return
  1032. },
  1033. /* Recursive divide and conquer multiply algorithm.
  1034. original by
  1035. Let u = u0 + u1*(b^n)
  1036. Let v = v0 + v1*(b^n)
  1037. Then uv = (B^2n+B^n)*u1*v1 + B^n*(u1-u0)*(v0-v1) + (B^n+1)*u0*v0
  1038. B is the base of storage, number of digits in u1,u0 close to equal.
  1039. */
  1040. _bc_rec_mul: function(u, ulen, v, vlen, full_scale) {
  1041. var prod; // @return
  1042. var u0, u1, v0, v1; //bc_num
  1043. var u0len, v0len; //int
  1044. var m1, m2, m3, d1, d2; //bc_num
  1045. var n, prodlen, m1zero; // int
  1046. var d1len, d2len; // int
  1047. // Base case?
  1048. if ((ulen + vlen) < libbcmath.MUL_BASE_DIGITS || ulen < libbcmath.MUL_SMALL_DIGITS || vlen < libbcmath.MUL_SMALL_DIGITS) {
  1049. return libbcmath._bc_simp_mul(u, ulen, v, vlen, full_scale);
  1050. }
  1051. // Calculate n -- the u and v split point in digits.
  1052. n = Math.floor((libbcmath.MAX(ulen, vlen) + 1) / 2);
  1053. // Split u and v.
  1054. if (ulen < n) {
  1055. u1 = libbcmath.bc_init_num(); //u1 = bc_copy_num (BCG(_zero_));
  1056. u0 = libbcmath.new_sub_num(ulen, 0, u.n_value);
  1057. } else {
  1058. u1 = libbcmath.new_sub_num(ulen - n, 0, u.n_value);
  1059. u0 = libbcmath.new_sub_num(n, 0, u.n_value + ulen - n);
  1060. }
  1061. if (vlen < n) {
  1062. v1 = libbcmath.bc_init_num(); //bc_copy_num (BCG(_zero_));
  1063. v0 = libbcmath.new_sub_num(vlen, 0, v.n_value);
  1064. } else {
  1065. v1 = libbcmath.new_sub_num(vlen - n, 0, v.n_value);
  1066. v0 = libbcmath.new_sub_num(n, 0, v.n_value + vlen - n);
  1067. }
  1068. libbcmath._bc_rm_leading_zeros(u1);
  1069. libbcmath._bc_rm_leading_zeros(u0);
  1070. u0len = u0.n_len;
  1071. libbcmath._bc_rm_leading_zeros(v1);
  1072. libbcmath._bc_rm_leading_zeros(v0);
  1073. v0len = v0.n_len;
  1074. m1zero = libbcmath.bc_is_zero(u1) || libbcmath.bc_is_zero(v1);
  1075. // Calculate sub results ...
  1076. d1 = libbcmath.bc_init_num(); // needed?
  1077. d2 = libbcmath.bc_init_num(); // needed?
  1078. d1 = libbcmath.bc_sub(u1, u0, 0);
  1079. d1len = d1.n_len;
  1080. d2 = libbcmath.bc_sub(v0, v1, 0);
  1081. d2len = d2.n_len;
  1082. // Do recursive multiplies and shifted adds.
  1083. if (m1zero) {
  1084. m1 = libbcmath.bc_init_num(); //bc_copy_num (BCG(_zero_));
  1085. } else {
  1086. //m1 = libbcmath.bc_init_num(); //allow pass-by-ref
  1087. m1 = libbcmath._bc_rec_mul(u1, u1.n_len, v1, v1.n_len, 0);
  1088. }
  1089. if (libbcmath.bc_is_zero(d1) || libbcmath.bc_is_zero(d2)) {
  1090. m2 = libbcmath.bc_init_num(); //bc_copy_num (BCG(_zero_));
  1091. } else {
  1092. //m2 = libbcmath.bc_init_num(); //allow pass-by-ref
  1093. m2 = libbcmath._bc_rec_mul(d1, d1len, d2, d2len, 0);
  1094. }
  1095. if (libbcmath.bc_is_zero(u0) || libbcmath.bc_is_zero(v0)) {
  1096. m3 = libbcmath.bc_init_num(); //bc_copy_num (BCG(_zero_));
  1097. } else {
  1098. //m3 = libbcmath.bc_init_num(); //allow pass-by-ref
  1099. m3 = libbcmath._bc_rec_mul(u0, u0.n_len, v0, v0.n_len, 0);
  1100. }
  1101. // Initialize product
  1102. prodlen = ulen + vlen + 1;
  1103. prod = libbcmath.bc_new_num(prodlen, 0);
  1104. if (!m1zero) {
  1105. libbcmath._bc_shift_addsub(prod, m1, 2 * n, 0);
  1106. libbcmath._bc_shift_addsub(prod, m1, n, 0);
  1107. }
  1108. libbcmath._bc_shift_addsub(prod, m3, n, 0);
  1109. libbcmath._bc_shift_addsub(prod, m3, 0, 0);
  1110. libbcmath._bc_shift_addsub(prod, m2, n, d1.n_sign != d2.n_sign);
  1111. return prod;
  1112. // Now clean up!
  1113. //bc_free_num (&u1);
  1114. //bc_free_num (&u0);
  1115. //bc_free_num (&v1);
  1116. //bc_free_num (&m1);
  1117. //bc_free_num (&v0);
  1118. //bc_free_num (&m2);
  1119. //bc_free_num (&m3);
  1120. //bc_free_num (&d1);
  1121. //bc_free_num (&d2);
  1122. },
  1123. /**
  1124. *
  1125. * @param {bc_num} n1
  1126. * @param {bc_num} n2
  1127. * @param {boolean} use_sign
  1128. * @param {boolean} ignore_last
  1129. * @return -1, 0, 1 (see bc_compare)
  1130. */
  1131. _bc_do_compare: function(n1, n2, use_sign, ignore_last) {
  1132. var n1ptr, n2ptr; // int
  1133. var count; // int
  1134. /* First, compare signs. */
  1135. if (use_sign && (n1.n_sign != n2.n_sign)) {
  1136. if (n1.n_sign == libbcmath.PLUS) {
  1137. return (1); /* Positive N1 > Negative N2 */
  1138. } else {
  1139. return (-1); /* Negative N1 < Positive N1 */
  1140. }
  1141. }
  1142. /* Now compare the magnitude. */
  1143. if (n1.n_len != n2.n_len) {
  1144. if (n1.n_len > n2.n_len) { /* Magnitude of n1 > n2. */
  1145. if (!use_sign || (n1.n_sign == libbcmath.PLUS)) {
  1146. return (1);
  1147. } else {
  1148. return (-1);
  1149. }
  1150. } else { /* Magnitude of n1 < n2. */
  1151. if (!use_sign || (n1.n_sign == libbcmath.PLUS)) {
  1152. return (-1);
  1153. } else {
  1154. return (1);
  1155. }
  1156. }
  1157. }
  1158. /* If we get here, they have the same number of integer digits.
  1159. check the integer part and the equal length part of the fraction. */
  1160. count = n1.n_len + Math.min(n1.n_scale, n2.n_scale);
  1161. n1ptr = 0;
  1162. n2ptr = 0;
  1163. while ((count > 0) && (n1.n_value[n1ptr] == n2.n_value[n2ptr])) {
  1164. n1ptr++;
  1165. n2ptr++;
  1166. count--;
  1167. }
  1168. if (ignore_last && (count == 1) && (n1.n_scale == n2.n_scale)) {
  1169. return (0);
  1170. }
  1171. if (count !== 0) {
  1172. if (n1.n_value[n1ptr] > n2.n_value[n2ptr]) { /* Magnitude of n1 > n2. */
  1173. if (!use_sign || n1.n_sign == libbcmath.PLUS) {
  1174. return (1);
  1175. } else {
  1176. return (-1);
  1177. }
  1178. } else { /* Magnitude of n1 < n2. */
  1179. if (!use_sign || n1.n_sign == libbcmath.PLUS) {
  1180. return (-1);
  1181. } else {
  1182. return (1);
  1183. }
  1184. }
  1185. }
  1186. /* They are equal up to the last part of the equal part of the fraction. */
  1187. if (n1.n_scale != n2.n_scale) {
  1188. if (n1.n_scale > n2.n_scale) {
  1189. for (count = (n1.n_scale - n2.n_scale); count > 0; count--) {
  1190. if (n1.n_value[n1ptr++] !== 0) { /* Magnitude of n1 > n2. */
  1191. if (!use_sign || n1.n_sign == libbcmath.PLUS) {
  1192. return (1);
  1193. } else {
  1194. return (-1);
  1195. }
  1196. }
  1197. }
  1198. } else {
  1199. for (count = (n2.n_scale - n1.n_scale); count > 0; count--) {
  1200. if (n2.n_value[n2ptr++] !== 0) { /* Magnitude of n1 < n2. */
  1201. if (!use_sign || n1.n_sign == libbcmath.PLUS) {
  1202. return (-1);
  1203. } else {
  1204. return (1);
  1205. }
  1206. }
  1207. }
  1208. }
  1209. }
  1210. /* They must be equal! */
  1211. return (0);
  1212. },
  1213. /* Here is the full subtract routine that takes care of negative numbers.
  1214. N2 is subtracted from N1 and the result placed in RESULT. SCALE_MIN
  1215. is the minimum scale for the result. */
  1216. bc_sub: function(n1, n2, scale_min) {
  1217. var diff; // bc_num
  1218. var cmp_res, res_scale; //int
  1219. if (n1.n_sign != n2.n_sign) {
  1220. diff = libbcmath._bc_do_add(n1, n2, scale_min);
  1221. diff.n_sign = n1.n_sign;
  1222. } else { /* subtraction must be done. */
  1223. /* Compare magnitudes. */
  1224. cmp_res = libbcmath._bc_do_compare(n1, n2, false, false);
  1225. switch (cmp_res) {
  1226. case -1:
  1227. /* n1 is less than n2, subtract n1 from n2. */
  1228. diff = libbcmath._bc_do_sub(n2, n1, scale_min);
  1229. diff.n_sign = (n2.n_sign == libbcmath.PLUS ? libbcmath.MINUS : libbcmath.PLUS);
  1230. break;
  1231. case 0:
  1232. /* They are equal! return zero! */
  1233. res_scale = libbcmath.MAX(scale_min, libbcmath.MAX(n1.n_scale, n2.n_scale));
  1234. diff = libbcmath.bc_new_num(1, res_scale);
  1235. libbcmath.memset(diff.n_value, 0, 0, res_scale + 1);
  1236. break;
  1237. case 1:
  1238. /* n2 is less than n1, subtract n2 from n1. */
  1239. diff = libbcmath._bc_do_sub(n1, n2, scale_min);
  1240. diff.n_sign = n1.n_sign;
  1241. break;
  1242. }
  1243. }
  1244. /* Clean up and return. */
  1245. //bc_free_num (result);
  1246. //*result = diff;
  1247. return diff;
  1248. },
  1249. _bc_do_add: function(n1, n2, scale_min) {
  1250. var sum; // bc_num
  1251. var sum_scale, sum_digits; // int
  1252. var n1ptr, n2ptr, sumptr; // int
  1253. var carry, n1bytes, n2bytes; // int
  1254. var tmp; // int
  1255. // Prepare sum.
  1256. sum_scale = libbcmath.MAX(n1.n_scale, n2.n_scale);
  1257. sum_digits = libbcmath.MAX(n1.n_len, n2.n_len) + 1;
  1258. sum = libbcmath.bc_new_num(sum_digits, libbcmath.MAX(sum_scale, scale_min));
  1259. /* Not needed?
  1260. if (scale_min > sum_scale) {
  1261. sumptr = (char *) (sum->n_value + sum_scale + sum_digits);
  1262. for (count = scale_min - sum_scale; count > 0; count--) {
  1263. *sumptr++ = 0;
  1264. }
  1265. }
  1266. */
  1267. // Start with the fraction part. Initialize the pointers.
  1268. n1bytes = n1.n_scale;
  1269. n2bytes = n2.n_scale;
  1270. n1ptr = (n1.n_len + n1bytes - 1);
  1271. n2ptr = (n2.n_len + n2bytes - 1);
  1272. sumptr = (sum_scale + sum_digits - 1);
  1273. // Add the fraction part. First copy the longer fraction (ie when adding 1.2345 to 1 we know .2345 is correct already) .
  1274. if (n1bytes != n2bytes) {
  1275. if (n1bytes > n2bytes) {
  1276. // n1 has more dp then n2
  1277. while (n1bytes > n2bytes) {
  1278. sum.n_value[sumptr--] = n1.n_value[n1ptr--];
  1279. // *sumptr-- = *n1ptr--;
  1280. n1bytes--;
  1281. }
  1282. } else {
  1283. // n2 has more dp then n1
  1284. while (n2bytes > n1bytes) {
  1285. sum.n_value[sumptr--] = n2.n_value[n2ptr--];
  1286. // *sumptr-- = *n2ptr--;
  1287. n2bytes--;
  1288. }
  1289. }
  1290. }
  1291. // Now add the remaining fraction part and equal size integer parts.
  1292. n1bytes += n1.n_len;
  1293. n2bytes += n2.n_len;
  1294. carry = 0;
  1295. while ((n1bytes > 0) && (n2bytes > 0)) {
  1296. // add the two numbers together
  1297. tmp = n1.n_value[n1ptr--] + n2.n_value[n2ptr--] + carry;
  1298. // *sumptr = *n1ptr-- + *n2ptr-- + carry;
  1299. // check if they are >= 10 (impossible to be more then 18)
  1300. if (tmp >= libbcmath.BASE) {
  1301. carry = 1;
  1302. tmp -= libbcmath.BASE; // yep, subtract 10, add a carry
  1303. } else {
  1304. carry = 0;
  1305. }
  1306. sum.n_value[sumptr] = tmp;
  1307. sumptr--;
  1308. n1bytes--;
  1309. n2bytes--;
  1310. }
  1311. // Now add carry the [rest of the] longer integer part.
  1312. if (n1bytes === 0) {
  1313. // n2 is a bigger number then n1
  1314. while (n2bytes-- > 0) {
  1315. tmp = n2.n_value[n2ptr--] + carry;
  1316. // *sumptr = *n2ptr-- + carry;
  1317. if (tmp >= libbcmath.BASE) {
  1318. carry = 1;
  1319. tmp -= libbcmath.BASE;
  1320. } else {
  1321. carry = 0;
  1322. }
  1323. sum.n_value[sumptr--] = tmp;
  1324. }
  1325. } else {
  1326. // n1 is bigger then n2..
  1327. while (n1bytes-- > 0) {
  1328. tmp = n1.n_value[n1ptr--] + carry;
  1329. // *sumptr = *n1ptr-- + carry;
  1330. if (tmp >= libbcmath.BASE) {
  1331. carry = 1;
  1332. tmp -= libbcmath.BASE;
  1333. } else {
  1334. carry = 0;
  1335. }
  1336. sum.n_value[sumptr--] = tmp;
  1337. }
  1338. }
  1339. // Set final carry.
  1340. if (carry == 1) {
  1341. sum.n_value[sumptr] += 1;
  1342. // *sumptr += 1;
  1343. }
  1344. // Adjust sum and return.
  1345. libbcmath._bc_rm_leading_zeros(sum);
  1346. return sum;
  1347. },
  1348. /**
  1349. * Perform a subtraction
  1350. *
  1351. // Perform subtraction: N2 is subtracted from N1 and the value is
  1352. // returned. The signs of N1 and N2 are ignored. Also, N1 is
  1353. // assumed to be larger than N2. SCALE_MIN is the minimum scale
  1354. // of the result.
  1355. *
  1356. * Basic school maths says to subtract 2 numbers..
  1357. * 1. make them the same length, the decimal places, and the integer part
  1358. * 2. start from the right and subtract the two numbers from each other
  1359. * 3. if the sum of the 2 numbers < 0, carry -1 to the next set and add 10 (ie 18 > carry 1 becomes 8). thus 0.9 + 0.9 = 1.8
  1360. *
  1361. * @param {bc_num} n1
  1362. * @param {bc_num} n2
  1363. * @param {int} scale_min
  1364. * @return bc_num
  1365. */
  1366. _bc_do_sub: function(n1, n2, scale_min) {
  1367. var diff; //bc_num
  1368. var diff_scale, diff_len; // int
  1369. var min_scale, min_len; // int
  1370. var n1ptr, n2ptr, diffptr; // int
  1371. var borrow, count, val; // int
  1372. // Allocate temporary storage.
  1373. diff_len = libbcmath.MAX(n1.n_len, n2.n_len);
  1374. diff_scale = libbcmath.MAX(n1.n_scale, n2.n_scale);
  1375. min_len = libbcmath.MIN(n1.n_len, n2.n_len);
  1376. min_scale = libbcmath.MIN(n1.n_scale, n2.n_scale);
  1377. diff = libbcmath.bc_new_num(diff_len, libbcmath.MAX(diff_scale, scale_min));
  1378. /* Not needed?
  1379. // Zero extra digits made by scale_min.
  1380. if (scale_min > diff_scale) {
  1381. diffptr = (char *) (diff->n_value + diff_len + diff_scale);
  1382. for (count = scale_min - diff_scale; count > 0; count--) {
  1383. *diffptr++ = 0;
  1384. }
  1385. }
  1386. */
  1387. // Initialize the subtract.
  1388. n1ptr = (n1.n_len + n1.n_scale - 1);
  1389. n2ptr = (n2.n_len + n2.n_scale - 1);
  1390. diffptr = (diff_len + diff_scale - 1);
  1391. // Subtract the numbers.
  1392. borrow = 0;
  1393. // Take care of the longer scaled number.
  1394. if (n1.n_scale != min_scale) {
  1395. // n1 has the longer scale
  1396. for (count = n1.n_scale - min_scale; count > 0; count--) {
  1397. diff.n_value[diffptr--] = n1.n_value[n1ptr--];
  1398. // *diffptr-- = *n1ptr--;
  1399. }
  1400. } else {
  1401. // n2 has the longer scale
  1402. for (count = n2.n_scale - min_scale; count > 0; count--) {
  1403. val = 0 - n2.n_value[n2ptr--] - borrow;
  1404. //val = - *n2ptr-- - borrow;
  1405. if (val < 0) {
  1406. val += libbcmath.BASE;
  1407. borrow = 1;
  1408. } else {
  1409. borrow = 0;
  1410. }
  1411. diff.n_value[diffptr--] = val;
  1412. //*diffptr-- = val;
  1413. }
  1414. }
  1415. // Now do the equal length scale and integer parts.
  1416. for (count = 0; count < min_len + min_scale; count++) {
  1417. val = n1.n_value[n1ptr--] - n2.n_value[n2ptr--] - borrow;
  1418. //val = *n1ptr-- - *n2ptr-- - borrow;
  1419. if (val < 0) {
  1420. val += libbcmath.BASE;
  1421. borrow = 1;
  1422. } else {
  1423. borrow = 0;
  1424. }
  1425. diff.n_value[diffptr--] = val;
  1426. //*diffptr-- = val;
  1427. }
  1428. // If n1 has more digits then n2, we now do that subtract.
  1429. if (diff_len != min_len) {
  1430. for (count = diff_len - min_len; count > 0; count--) {
  1431. val = n1.n_value[n1ptr--] - borrow;
  1432. // val = *n1ptr-- - borrow;
  1433. if (val < 0) {
  1434. val += libbcmath.BASE;
  1435. borrow = 1;
  1436. } else {
  1437. borrow = 0;
  1438. }
  1439. diff.n_value[diffptr--] = val;
  1440. }
  1441. }
  1442. // Clean up and return.
  1443. libbcmath._bc_rm_leading_zeros(diff);
  1444. return diff;
  1445. },
  1446. /**
  1447. *
  1448. * @param {int} length
  1449. * @param {int} scale
  1450. * @return bc_num
  1451. */
  1452. bc_new_num: function(length, scale) {
  1453. var temp; // bc_num
  1454. temp = new libbcmath.bc_num();
  1455. temp.n_sign = libbcmath.PLUS;
  1456. temp.n_len = length;
  1457. temp.n_scale = scale;
  1458. temp.n_value = libbcmath.safe_emalloc(1, length + scale, 0);
  1459. libbcmath.memset(temp.n_value, 0, 0, length + scale);
  1460. return temp;
  1461. },
  1462. safe_emalloc: function(size, len, extra) {
  1463. return Array((size * len) + extra);
  1464. },
  1465. /**
  1466. * Create a new number
  1467. */
  1468. bc_init_num: function() {
  1469. return new libbcmath.bc_new_num(1, 0);
  1470. },
  1471. _bc_rm_leading_zeros: function(num) { /* We can move n_value to point to the first non zero digit! */
  1472. while ((num.n_value[0] === 0) && (num.n_len > 1)) {
  1473. num.n_value.shift();
  1474. num.n_len--;
  1475. }
  1476. },
  1477. /**
  1478. * Convert to bc_num detecting scale
  1479. */
  1480. php_str2num: function(str) {
  1481. var p;
  1482. p = str.indexOf('.');
  1483. if (p == -1) {
  1484. return libbcmath.bc_str2num(str, 0);
  1485. } else {
  1486. return libbcmath.bc_str2num(str, (str.length - p));
  1487. }
  1488. },
  1489. CH_VAL: function(c) {
  1490. return c - '0'; //??
  1491. },
  1492. BCD_CHAR: function(d) {
  1493. return d + '0'; // ??
  1494. },
  1495. isdigit: function(c) {
  1496. return (isNaN(parseInt(c, 10)) ? false : true);
  1497. },
  1498. bc_str2num: function(str_in, scale) {
  1499. var str, num, ptr, digits, strscale, zero_int, nptr;
  1500. // remove any non-expected characters
  1501. /* Check for valid number and count digits. */
  1502. str = str_in.split(''); // convert to array
  1503. ptr = 0; // str
  1504. digits = 0;
  1505. strscale = 0;
  1506. zero_int = false;
  1507. if ((str[ptr] === '+') || (str[ptr] === '-')) {
  1508. ptr++; /* Sign */
  1509. }
  1510. while (str[ptr] === '0') {
  1511. ptr++; /* Skip leading zeros. */
  1512. }
  1513. //while (libbcmath.isdigit(str[ptr])) {
  1514. while ((str[ptr]) % 1 === 0) { //libbcmath.isdigit(str[ptr])) {
  1515. ptr++;
  1516. digits++; /* digits */
  1517. }
  1518. if (str[ptr] === '.') {
  1519. ptr++; /* decimal point */
  1520. }
  1521. //while (libbcmath.isdigit(str[ptr])) {
  1522. while ((str[ptr]) % 1 === 0) { //libbcmath.isdigit(str[ptr])) {
  1523. ptr++;
  1524. strscale++; /* digits */
  1525. }
  1526. if ((str[ptr]) || (digits + strscale === 0)) {
  1527. // invalid number, return 0
  1528. return libbcmath.bc_init_num();
  1529. //*num = bc_copy_num (BCG(_zero_));
  1530. }
  1531. /* Adjust numbers and allocate storage and initialize fields. */
  1532. strscale = libbcmath.MIN(strscale, scale);
  1533. if (digits === 0) {
  1534. zero_int = true;
  1535. digits = 1;
  1536. }
  1537. num = libbcmath.bc_new_num(digits, strscale);
  1538. /* Build the whole number. */
  1539. ptr = 0; // str
  1540. if (str[ptr] === '-') {
  1541. num.n_sign = libbcmath.MINUS;
  1542. //(*num)->n_sign = MINUS;
  1543. ptr++;
  1544. } else {
  1545. num.n_sign = libbcmath.PLUS;
  1546. //(*num)->n_sign = PLUS;
  1547. if (str[ptr] === '+') {
  1548. ptr++;
  1549. }
  1550. }
  1551. while (str[ptr] === '0') {
  1552. ptr++; /* Skip leading zeros. */
  1553. }
  1554. nptr = 0; //(*num)->n_value;
  1555. if (zero_int) {
  1556. num.n_value[nptr++] = 0;
  1557. digits = 0;
  1558. }
  1559. for (; digits > 0; digits--) {
  1560. num.n_value[nptr++] = libbcmath.CH_VAL(str[ptr++]);
  1561. //*nptr++ = CH_VAL(*ptr++);
  1562. }
  1563. /* Build the fractional part. */
  1564. if (strscale > 0) {
  1565. ptr++; /* skip the decimal point! */
  1566. for (; strscale > 0; strscale--) {
  1567. num.n_value[nptr++] = libbcmath.CH_VAL(str[ptr++]);
  1568. }
  1569. }
  1570. return num;
  1571. },
  1572. cint: function(v) {
  1573. if (typeof v === 'undefined') {
  1574. v = 0;
  1575. }
  1576. var x = parseInt(v, 10);
  1577. if (isNaN(x)) {
  1578. x = 0;
  1579. }
  1580. return x;
  1581. },
  1582. /**
  1583. * Basic min function
  1584. * @param {int} a
  1585. * @param {int} b
  1586. */
  1587. MIN: function(a, b) {
  1588. return ((a > b) ? b : a);
  1589. },
  1590. /**
  1591. * Basic max function
  1592. * @param {int} a
  1593. * @param {int} b
  1594. */
  1595. MAX: function(a, b) {
  1596. return ((a > b) ? a : b);
  1597. },
  1598. /**
  1599. * Basic odd function
  1600. * @param {int} a
  1601. */
  1602. ODD: function(a) {
  1603. return (a & 1);
  1604. },
  1605. /**
  1606. * replicate c function
  1607. * @param {array} r return (by reference)
  1608. * @param {int} ptr
  1609. * @param {string} chr char to fill
  1610. * @param {int} len length to fill
  1611. */
  1612. memset: function(r, ptr, chr, len) {
  1613. var i;
  1614. for (i = 0; i < len; i++) {
  1615. r[ptr + i] = chr;
  1616. }
  1617. },
  1618. /**
  1619. * Replacement c function
  1620. * Obviously can't work like c does, so we've added an "offset" param so you could do memcpy(dest+1, src, len) as memcpy(dest, 1, src, len)
  1621. * Also only works on arrays
  1622. */
  1623. memcpy: function(dest, ptr, src, srcptr, len) {
  1624. var i;
  1625. for (i = 0; i < len; i++) {
  1626. dest[ptr + i] = src[srcptr + i];
  1627. }
  1628. return true;
  1629. },
  1630. /**
  1631. * Determine if the number specified is zero or not
  1632. * @param {bc_num} num number to check
  1633. * @return boolean true when zero, false when not zero.
  1634. */
  1635. bc_is_zero: function(num) {
  1636. var count; // int
  1637. var nptr; // int
  1638. /* Quick check. */
  1639. //if (num == BCG(_zero_)) return TRUE;
  1640. /* Initialize */
  1641. count = num.n_len + num.n_scale;
  1642. nptr = 0; //num->n_value;
  1643. /* The check */
  1644. while ((count > 0) && (num.n_value[nptr++] === 0)) {
  1645. count--;
  1646. }
  1647. if (count !== 0) {
  1648. return false;
  1649. } else {
  1650. return true;
  1651. }
  1652. },
  1653. bc_out_of_memory: function() {
  1654. throw new Error('(BC) Out of memory');
  1655. }
  1656. };
  1657. return libbcmath;
  1658. }