## Edit: bcmod

 Function: Description: Get the modulus of the left_operand using modulus.
Edit function
 Code: /* Note: this function is a hack, and it only supports the use cases I require at the moment, being: an arbitrary precision decimal left_operand and native precision positive decimal modulus (must fit in a native number, i.e. a double). */ function bcmod( left_operand, modulus ) { // John was here! // Key was here! var i, d; function split( operand ) { var parts = operand.split( '.' ); var i = parts[ 0 ]; var d = '0.' + ( parts.length > 1 ? parts[ 1 ] : '0' ); return { "i": i, "d": d }; } //modulus = Math.round( parseFloat( modulus ) ); modulus = parseFloat( modulus ); modulus = abs( modulus ); if ( modulus === 0 ) { return null; } var take = 4; var modulus_limit = Math.pow( 10, take ); if ( modulus >= modulus_limit ) { throw new Error( "Modulus cannot be " + modulus_limit + " or greater." ); } var result = 0; var r = split( left_operand ); i = r.i; d = r.d; var read_length = 0; function read() { read_length = i.length < take ? i.length : ( take ); var result = i.substr( 0, take ); i = i.substr( take ); return result; } function round( value ) { //console.log( "V:" + value ); //0.8999999999999997 //0.09999999999999984 //0.29999999999999993 //0.7999999999999998 //0.8999999999999999 //0.10000000000000009 //0.029999999999999985 var units = '0.0000000000000000'; function get_chars( s ) { var result = []; for ( var j = 0, jl = s.length; j < jl; j++ ) { result.unshift( s.charAt( j ) ); } return result; } value = value.toString(); var r = split( value ); var d_chars = get_chars( r.d.substring( 0, units.length ) ); //console.log( "D:" + d_chars.toString() ); var carry = 0; for ( var ci = 0, cl = d_chars.length; ci < cl; ci++ ) { var c = d_chars[ ci ]; if ( ! /^[0-9]\$/.test( c ) ) { break; } if ( ci === 0 && cl >= units.length ) { carry = Math.round( parseFloat( '0.' + c ) ); d_chars[ ci ] = '0'; } else { var v = parseInt( c ) + carry; if ( v >= 10 ) { carry = 1; v -= 10; } else { carry = 0; } d_chars[ ci ] = v.toString(); } } var result = ( parseInt( r.i ) + carry ).toString() + array_reverse( d_chars.slice( 0, -1 ) ).join( '' ).replace( /[0.]*\$/, '' ); //console.log( "N:" + result ); return result; } do { var n = parseInt( read() ); //console.log( result ); result = ( result * Math.pow( 10, read_length ) + n ) % modulus; var temp = parseFloat( round( result ) ); //console.log( "R:" + result ); //console.log( "T:" + temp ); if ( ( temp - modulus ) >= 0 ) { temp -= modulus; //console.log( "T:" + temp ); result = temp; } } while ( i.length > 0 ); result += parseFloat( d ); var test = result - modulus; result = test < 0 ? result : test; result = round( result ); //console.log( result ); //console.log(); return result; } You have to be logged in to edit functions.
Edit tests
 Code: function bcmod_tests() { // API reference: http://docs.jquery.com/QUnit module( "bcmod" ); test( "bcmod", function() { // some basic modulus cases: equal( bcmod( '4', '2' ), '0', "bcmod( '4', '2' )" ); equal( bcmod( '2', '4' ), '2', "bcmod( '2', '4' )" ); equal( bcmod( '123456', '1000' ), '456', "bcmod( '123456', '1000' )" ); equal( bcmod( '12345', '1000' ), '345', "bcmod( '12345', '1000' )" ); equal( bcmod( '1234', '1000' ), '234', "bcmod( '1234', '1000' )" ); equal( bcmod( '123', '1000' ), '123', "bcmod( '123', '1000' )" ); equal( bcmod( '12', '1000' ), '12', "bcmod( '12', '1000' )" ); equal( bcmod( '1', '1000' ), '1', "bcmod( '1', '1000' )" ); equal( bcmod( '123456', '100' ), '56', "bcmod( '123456', '100' )" ); equal( bcmod( '12345', '100' ), '45', "bcmod( '12345', '100' )" ); equal( bcmod( '1234', '100' ), '34', "bcmod( '1234', '100' )" ); equal( bcmod( '123', '100' ), '23', "bcmod( '123', '100' )" ); equal( bcmod( '12', '100' ), '12', "bcmod( '12', '100' )" ); equal( bcmod( '1', '100' ), '1', "bcmod( '1', '100' )" ); equal( bcmod( '123456', '10' ), '6', "bcmod( '123456', '10' )" ); equal( bcmod( '12345', '10' ), '5', "bcmod( '12345', '10' )" ); equal( bcmod( '1234', '10' ), '4', "bcmod( '1234', '10' )" ); equal( bcmod( '123', '10' ), '3', "bcmod( '123', '10' )" ); equal( bcmod( '12', '10' ), '2', "bcmod( '12', '10' )" ); equal( bcmod( '1', '10' ), '1', "bcmod( '1', '10' )" ); equal( bcmod( '123456', '1' ), '0', "bcmod( '123456', '1' )" ); equal( bcmod( '12345', '1' ), '0', "bcmod( '12345', '1' )" ); equal( bcmod( '1234', '1' ), '0', "bcmod( '1234', '1' )" ); equal( bcmod( '123', '1' ), '0', "bcmod( '123', '1' )" ); equal( bcmod( '12', '1' ), '0', "bcmod( '12', '1' )" ); equal( bcmod( '1', '1' ), '0', "bcmod( '1', '1' )" ); // fractional modulus is now supported: equal( bcmod( '10', '1.3' ), '0.9', "bcmod( '10', '1.3' )" ); // testing negative left_operand: equal( bcmod( '-11', '2' ), '-1', "bcmod( '-11', '2' )" ); // testing zero modulus and fractional modulus: equal( bcmod( '3', '0' ), null, "bcmod( '3', '0' )" ); equal( bcmod( '3', '0.0' ), null, "bcmod( '3', '0.0' )" ); bcmod_test( 3, 0.1, 0, 0.09999999999999984 ); bcmod_test( 3, 0.11, 0.03, 0.029999999999999985 ); bcmod_test( 3, 0.111, 0.003, 0.002999999999999961 ); equal( bcmod( '3', '0.5' ), '0', "bcmod( '3', '0.5' )" ); equal( bcmod( '3', '0.9' ), '0.3', "bcmod( '3', '0.9' )" ); equal( bcmod( '3', '1' ), '0', "bcmod( '3', '1' )" ); equal( bcmod( '3', '1.0' ), '0', "bcmod( '3', '1.0' )" ); equal( bcmod( '3', '1.1' ), '0.8', "bcmod( '3', '1.1' )" ); equal( bcmod( '3', '1.5' ), '0', "bcmod( '3', '1.5' )" ); equal( bcmod( '3', '1.9' ), '1.1', "bcmod( '3', '1.9' )" ); equal( bcmod( '3', '2' ), '1', "bcmod( '3', '2' )" ); equal( bcmod( '3', '2.0' ), '1', "bcmod( '3', '2.0' )" ); equal( bcmod( '3', '2.1' ), '0.9', "bcmod( '3', '2.1' )" ); equal( bcmod( '3', '2.5' ), '0.5', "bcmod( '3', '2.5' )" ); equal( bcmod( '3', '2.9' ), '0.1', "bcmod( '3', '2.9' )" ); equal( bcmod( '3', '3' ), '0', "bcmod( '3', '3' )" ); ok( true, "all pass" ); } ); } function bcmod_test( left_operand, modulus, expect, broken_js ) { if ( typeof broken_js === "undefined" ) { broken_js = expect; } equal( left_operand % modulus, broken_js, left_operand + " % " + modulus ); equal( bcmod( left_operand.toString(), modulus.toString() ), expect.toString(), "bcmod( '" + left_operand + "', '" + modulus + "' )" ); } You have to be logged in to edit tests.
Edit benchmark
 Code: function bcmod_benchmark() { for ( var i = 0; i < 1000; i++ ) { var result = bcmod( '123456', i.toString() ); } } You have to be logged in to edit benchmarks.
[top]