UNPKG

cejs

Version:

A JavaScript module framework that is simple to use.

506 lines 26 kB
�� /** * @name CeL quotient function * @fileoverview * ,g�jHhS+T�N quotient �v functions0 * @since 2010/3/11 16:59:59 * @example * <code> * CeL.run('data.math'); * // TODO: bug * CeL.run('data.math.quotient'); * var q1 = new CeL.quotient(2,3); * // xeW[�W�^�vI��c: * CeL.log(CeL.quotient.parse_base('4877.6'.toLowerCase(),10).to_base(16).replace(/_([^\(]+)/,'_<i style="text-decoration:overline">$1</i>')); * </code> */ /* TODO: use {String} value + {Number} exponent http://www.leemon.com/crypto/BigInt.html http://www-cs-students.stanford.edu/~tjw/jsbn/ http://java.sun.com/javase/6/docs/api/java/math/BigInteger.html */ 'use strict'; if (typeof CeL === 'function') CeL.run( { name:'data.math.quotient', require : 'data.math.to_rational_number|data.math.GCD|data.math.factorization', code : function(library_namespace) { // requiring var to_rational_number = this.r('to_rational_number'), GCD = this.r('GCD'), factorization = this.r('factorization'); //library_namespace.debug(to_rational_number); //library_namespace.debug(GCD); //============================================================================ // definition of module quotient var /* texe�R Rxe fraction wRxe proper fraction vinculum = "divide by" */ /** * gtxe rational number � gtpehQSOn0d0O0�0ƖTo0W0p0W0p00FU�0asTY0�0 integer n0-��eW[�0h0�00*YW[n0 Q g0h�Y00<br /> * 傁�8�eQ N T�W�^�vxe<P �ˊ(u parse_base() * * @param numerator RP[ * @param [denominator] R�k * @param {Boolean}[approximate] �Sя<O<P * * @example * <code> * CeL.log((new CeL.integer(3,4)).count('*',new CeL.integer(2,7)).reduce().to_print_mode()); * </code> * * @class integer �v functions * @constructor */ _// JSDT:_module_ = function(numerator, denominator, approximate) { if (typeof numerator === 'object' && numerator instanceof _ //&& numerator.Class === 'quotient' ) return numerator; if (isNaN(numerator)) numerator = 0; if (!denominator || isNaN(denominator)) denominator = 1; else if (denominator < 0) denominator = -denominator, numerator = -numerator; // to_rational_number � test �&N�V�P(RP[,R�k,���])� var q = to_rational_number(numerator); //library_namespace.debug(numerator + ' �! ' + q); if (!q) numerator = 0; else if (approximate || !q[2]) // !q���]BfO(uKN numerator = q[0], denominator *= q[1] || 1; else while (numerator % 1 || denominator % 1) // S�ptexe numerator *= 10, denominator *= 10; // value this.n = numerator, this.d = denominator; // this.type='quotient'; //library_namespace.debug(this.n + ' / ' + this.d); return this; }; //class public interface --------------------------- _// JSDT:_module_ . /** * �_�t�{R��&{_�� {String} texe.\xe__repetend_separator__�_�t�{ * @_memberOf _module_ */ repetend_separator = '_';//' ' _// JSDT:_module_ . /** * xeW[Ɩ * @_memberOf _module_ * @see * <a href="http://en.wikipedia.org/wiki/Numerical_digit" accessdate="2010/4/16 20:47">Numerical digit</a> */ digit_char = '0123456789abcdefghijklmnopqrstuvwxyz';//.split('') _// JSDT:_module_ . /** * I��cc�[2�MO�vxeW[b�p quotient ir�N * @since 2004/7/9 16:13 * @param number xeW[ * @param base �W�^ * @param {String}[digit_chars] �_�t\xe digit W[Ɩ0 * @return �V�P quotient ir�N �ˊ(u quotient.to_base() �P�V@b2kKN base * @_memberOf _module_ * @example * var q=parse_base('10000.'+_.repetend_separator+'3',11); * if(!q) * alert('bad input!'); * else * library_namespace.debug('<br />'+q.base(8)+','+q.base()+' , '+q.to_print_mode()+','+q.print(1)+','+q.to_print_mode(2)+','+q.to_print_mode(3,0,'',5)); */ parse_base = function(number, base, digit_char) { // if(!num) num = 0; if ((!(base = Math.floor(base)) || base < 2) && digit_char) base = digit_char.length; if (!digit_char) digit_char = _.digit_char; if (isNaN(base) || base < 2 || digit_char.length < base) base = 10; if (!number || base === 10 && ('' + number).indexOf(_.repetend_separator) === -1) // �S�� g�_�t\xe �@b�N N��>eN��P�P base === 10 return new _(number); var i = 0, n = new _(0, 1), m = 0, t = 0, p, c = {}, r = new _(0, 1); for (; i < digit_char.length; i++) c[digit_char.charAt(i)] = i; // W[Ɩ number += '', i = -1, n.d = r.d = 1; //library_namespace.debug('<br />'+i+','+num.length+','+t+','+num+','+n.to_print_mode()); if (number.charAt(0) === '-') i = 0, m = 1; while (++i < number.length && (p = number.charAt(i)) != '.') // texe if (isNaN(p = c[p]) || p >= base) // error! return; else t = t * base + p; //library_namespace.debug('<br />'+i+','+num.length+','+t+','+num+','+n.to_print_mode()); while (++i < number.length && (p = number.charAt(i)) != _.repetend_separator) // \xe if (isNaN(p = c[p]) || p >= base) // error! return; else n.n = n.n * base + p, n.d *= base; while (++i < number.length) // �_�t�{ if (isNaN(p = c[number.charAt(i)]) || p >= base) return; // error! else r.n = r.n * base + p, r.d *= base; //library_namespace.debug('<br />**'+n.to_print_mode()); // �U�_ n = n.count('+=', t); if (r.n) r.d = (r.d - 1) * n.d, n.count('+=', r); n.reduce(); //library_namespace.debug('<br />*'+n.to_print_mode()); if (m) n.n = -n.n; return n; }; _// JSDT:_module_ .prototype = { // instance public interface ------------------- /** * g!|Rxe/S!|, }R reduction * @return S!|�_�v * @_name _module_.prototype.reduce */ reduce : function() { var g = GCD(this.n, this.d); if (g && g > 1) this.n /= g, this.d /= g; return this; }, /** * �VGRK��{/�{xeK��{ + - * / (+-��), **, ^, [=] * @param op operator * @param q2 the second quotient * @return ��{�_�vP}�g * @see * <a href="http://www.javaworld.com.tw/jute/post/view?bid=35&amp;id=30169&amp;tpg=1&amp;ppg=1&amp;sty=1&amp;age=0#30169" accessdate="2010/4/16 20:47">JavaWorld@TW Java֊�X - post.view</a> * @_name _module_.prototype.count */ count : function(op, q2) { var q; if (op.slice(-1) === '=') q = this, op = op.slice(0, -1); else q = new _(this); q2 = new _(q2); //library_namespace.debug('<br />'+this.type+','+q.to_print_mode()+' , '+q2.to_print_mode()); if (op === '-') q2.n = -q2.n, op = '+'; else if (op === '/') { var t = q2.n; q2.n = q2.d, q2.d = t, op = '*'; } //library_namespace.debug('<br />'+q.to_print_mode(1)+','+q2.to_print_mode(1)); if (op === '+') q.n = q.n * q2.d + q.d * q2.n, q.d *= q2.d; else if (op === '*') q.n *= q2.n, q.d *= q2.d; // N! /fc N�v��XN (Factorial,power) else if ((op === '**' || op === '^') && q2.reduce().d === 1) { q.reduce(), q.n = Math.pow(q.n, q2.n), q.d = Math.pow(q.d, q2.n); return q; } else { library_namespace.error('illegal operator [' + op + ']!'); return this; } //library_namespace.debug('<br />'+q.to_print_mode(1)+','+q2.to_print_mode(1)); // other: error //library_namespace.debug('<br />_'+q.reduce().to_print_mode()); try { return q.reduce(); } catch (e) { } return q; }, /** * �Oc�[�W�^I�b�_�t\xe circulating decimal / repeating decimal0 * yr�k�`�l�S�N�naO(u .toString() �g�_�_Y0 * TODO: \xe * @since 2004/7/9 13:28 * @param base �W�^ * @param digit_char �_�t\xe digit W[Ɩ * @return (decimal/xeW[�Rstring,repunitIndex/�_�t�{Repetend�Q�s(W) * @see * <a href="http://mathworld.wolfram.com/RepeatingDecimal.html" accessdate="2010/4/16 20:47">Repeating Decimal -- from Wolfram MathWorld</a> * <a href="http://hk.geocities.com/goodprimes/OFrp.htm">�_�t\xe� }xe0 }KNpu^�0</a> * @_name _module_.prototype.to_base */ to_base : function(base, digit_char) { //if (!isNaN(digit_char)) digit_char += ''; if (typeof digit_char !== 'string' || digit_char.length < 2) // W[Ɩ digit_char = _.digit_char; // �W�^�-��p 10 2�MO if (!(base = Math.floor(base)) || base == 10 || // illegal base base < 2 || base > digit_char.length) return this.to_decimal(); this.reduce(); var d = this.d, o = this.n, i, t, m = 0, // find base �v�Vxe(factor) f = factorization(base); if (o < 0) // ��xe o = -o, m = 1; // find R�k�v�Vxe(factor)��W�^ base KN�NƖ( N��(uGCD) for (var i = 0, g = 1, t = d; i < f.length; i += 2) while (t % f[i] === 0) g *= f[i], t /= f[i]; // get texe integer �R �! out f = o % d; i = (o - f) / d; o = ''; while (i) t = i % base, i = (i - t) / base, o = digit_char.charAt(t) + o; if (!o) o = '0', m = 0; //library_namespace.debug('<br />_' + typeof o + ',' + (o || '(null)') + ',' + o); if (!f) return m ? '-' + o : o; // 2�eQ\xe o += '.'; // set �xef/R�kd, �xeresidue mark r=f, �_�t�{ Repetend location of out:l, �]�zl�v�Vxe s var r = f, l = o.length, s = 1; // do main loop // while(o.length-l<d){ // P�6R?MO: debug(u while (true) { //library_namespace.debug('<br />.'+r+','+f+'/'+d+'('+base+'),'+s+':'+g+','+o); if (!f) { // �S�Nted� �!q�_�t0 l = 0; break; } f *= base; if (s === g) { // R�k� base �]�N� t = f, f %= d, o += digit_char.charAt((t - f) / d); if (f === r) // bingo! �xe͑��Q�s ��_�t�{P}_g0 break; } else { // f � d �]�N� t = GCD(base, d), s *= t, f /= t, d /= t, // do the same thing t = f, f %= d, o += digit_char.charAt((t - f) / d), // r �͑-�..dkU� g&T�S���QOUL�? maybe not? r = f, l = o.length; } } // �U�_ if (l) o += '(' + (o.length - l) + ')', o = o.slice(0, l) + _.repetend_separator + o.substr(l); if (m) o = '-' + o; return o; }, /** * �pAS2�MOgsOS�v to_base()<br /> * �NP}֊�O�� �}Y�P�_ N�NY\? * @since 2004/7/9 13:47 * @return * @_name _module_.prototype.to_decimal */ to_decimal : function() { this.reduce(); var d = this.d, t = d, g = 1, m = 0, f, o = this.n; if (o < 0) o = -o, m = 1; // ��xe // find R�k�v 2,5 �Vxe while (t % 2 === 0) // O(u Nb��L�g �b bug: 8��Q .110011001100110011001100110011001100(2) g\� g===t===0, �c�c // �NP}֊�O�� �}Y�P�_ N�NY\? //g <<= 1, t >>= 1; g *= 2, t /= 2; while (t % 5 === 0) g *= 5, t /= 5; // get texe integer �R �! out f = o % d, o = (o - f) / d; //library_namespace.debug('<br />_'+typeof o+','+(o||'(null)')+','+o); if (!f) // Yu N+- return (m ? '-' : '') + o; // 2�eQ\xe o += '.'; // set �xef/R�kd, �xe residue mark r=f, �_�t�{ Repetend location of out:l, �]�zl�v�Vxe s var r = f, l = o.length, s = 1; // do main loop // while(o.length-l<d){// P�6R?MO:debug(u while (true) { //library_namespace.debug('<br />.'+r+','+f+'/'+d+','+s+':'+g+','+o); if (!f) { // �S�Nted� �!q�_�t0 l = 0; break; } f *= 10; if (s === g) { // R�k� base �]�N� t = f, f %= d, o += (t - f) / d; if (f === r) // bingo! �_�t�{P}_g break; } else { t = d % 5 === 0 ? d % 2 === 0 ? 10 : 5 : 2, s *= t, f /= t, d /= t, // do the same thing t = f, f %= d, o += (t - f) / d, // r �͑-�..dkU� g&T�S���QOUL�? maybe not? r = f, l = o.length; } } // �U�_ if (l) o += '(' + (o.length - l) + ')', o = o.slice(0, l) + _.repetend_separator + o.substr(l); if (m) o = '-' + o; return o; }, /* gHeMOxe0\xeMOxe http://technet.microsoft.com/zh-tw/library/ms190476.aspx Precision, Scale gHeMOxe/fxeW[�vMOxe0\xeMOxe/fxeW[-N(W\xeޞ�StP�vMOxe0�O�Y �123.45 � PxeW[�v gHeMOxe/f 5 �\xeMOxe/f 20 Precision is the number of digits in a number. Scale is the number of digits to the right of the decimal point in a number. For example, the number 123.45 has a precision of 5 and a scale of 2. */ /** * o�:ybT.z N T!j_�vxeW[ * @since 2004/7/9 14:23 * @param mode o�:y!j_ * 0 wRxe proper fraction0GPRxe improper fraction (U.S., British or Australian) or top-heavy fraction (British, occasionally North America), * 1 6^Rxe mixed numeral (often called a mixed number, also called a mixed fraction), * 2 �v�cd�(102�MO), * 3 I�b�_�t\xe repeating decimal,d��\xeޞ NdigitMOxe�^��Vhc�NeQ� �. * @param base �W�^ * @param sum_char o�:y6^RxeBf�Nh�texe�wRxeKN���vR��0Y�p' 'b'+'b''0 * @param digit I�b�_�t\xeBf ��Nh��_�t\xe digit W[Ɩ * @return {String} o�:y!j_xeW[ * @_name _module_.prototype.to_print_mode */ to_print_mode : function(mode, base, sum_char, digit) { if (mode < 3 || !mode) { if (mode === 2) return this.n / this.d; var p, f; if (!mode || this.n < this.d) p = this.n + '/' + this.d; else f = this.n % this.d, p = (this.n - f) / this.d + (f ? (sum_char || '+') + f + '/' + this.d : ''); return p; } if (mode === 3) { var n = this.to_base(base, sum_char); if (isNaN(digit)) return n; var f = n.indexOf(_.repetend_separator), b = n.indexOf('.'); if (f === -1 || !digit) return b === -1 ? n : digit ? n.slice(0, b + digit + 1) : n.slice(0, b); digit += b + 1, // �_�t�{ b = n.substr(f + 1), n = n.slice(0, f); while (n.length < digit) n += b; return n.slice(0, digit); } }, /** * ,nf�'Y\/�k'Y\ * @param q2 the second quotient * @return {Number} 0:==, <0:<, >0:> * @_name _module_.prototype.compare_to */ compare_to : function(q2) { q2 = new _(q2); return this.n * q2.d - this.d * q2.n; } }; // setup toString function _.prototype.toString = _.prototype.to_print_mode; return ( _// JSDT:_module_ ); } });