Function: bcmod version 518

Function:
Description: Get the modulus of the left_operand using modulus.
Version:
Status: old release
Date: 2012-03-17 02:09
Summary: Updating comment.
Programmer: jj5
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
/*
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 ) {
  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;
}
[top]

Comments

There are no comments yet, be the first!

Please Login or Register to post comments.