Last Update: May.26,2019

JavaScript Sample

動作確認: ○IE11(Win7) ○Firefox67(Win7) ○Chrome74(Win7)

■ 2進数の四則演算

Number of bits:
a:
b:
 a : 0000000100000000 (256)
 b : 1111111110000000 (-128)
a+b: 0000000010000000 (128)
a-b: 0000000110000000 (384)
a*b: 1000000000000000 (-32768)
a/b: 1111111111111110 (-2)
a%b: 0000000000000000 (0)
min: 1000000000000000 (-32768)
max: 0111111111111111 (32767)

■ ソース

var BIT = 32, SIGN = BIT - 1;

/* Two's Complement */
var two_s_complement = function(A) {
  var T = [], F = 0;
  for (var i = 0; i < BIT; i++) {
    T[i] = F == 0 ? A[i] : A[i] ^ 1;
    if (T[i]) F = 1;
  }
  return T;
};

/* Left Shift */
var lshift = function(A, V) {
  for (var i = SIGN; i > 0; i--) {
    A[i] = A[i-1];
  }
  A[0] = V;
};

/* Adder */
var adder = function(A, B) {
  var X = [0], S = [], C = [];
  for (var i = 0; i < BIT; i++) {
    /* Half Adder */
    S[i] = A[i] ^ B[i];
    C[i] = A[i] & B[i];
    if (i == 0) continue;
    /* Full Adder */
    X[i] = C[i];
    C[i] = S[i] & C[i-1];
    S[i] ^= C[i-1];
    C[i] |= X[i];
  }
  return S;
};

/* Subtractor */
var subtractor = function(A, B) {
  return adder(A, two_s_complement(B));
};

/* Multiplier */
var multiplier = function(A, B) {
  var X = [], P = [];
  for (var i = 0; i < BIT; i++) {
    X[i] = A[i];
    P[i] = 0;
  }
  for (var i = 0; i < BIT; i++) {
    if (B[i]) P = adder(P, X);
    lshift(X, 0);
  }
  return P;
};

/* Divider */
var divider = function(A, B, F) {
  var N = A[SIGN] ? two_s_complement(A) : A;
  var D = B[SIGN] ? two_s_complement(B) : B;
  var Q = [], R = [], T;
  for (var i = 0; i < BIT; i++) {
    Q[i] = R[i] = 0;
  }
  for (var i = SIGN; i >= 0; i--) {
    lshift(R, N[i]);
    if ((T = subtractor(R, D))[SIGN] == 0) {
      R = T;
      Q[i] = 1;
    }
  }
  if (F) return A[SIGN] ? two_s_complement(R) : R;
  return A[SIGN] ^ B[SIGN] ? two_s_complement(Q) : Q;
};

/* Remainder */
var remainder = function(A, B) {
  return divider(A, B, 1);
};

/* Helper Functions */
var _bits = function(n) {
  var s = (n >>> 0).toString(2).split('').reverse();
  var a = [];
  for (var i = 0; i < BIT; i++) {
    a[i] = i < s.length ? s[i] | 0 : 0;
  }
  return a;
};

var _value_of = function(arr) {
  var r = arr[SIGN] ? two_s_complement(arr) : arr.concat();
  var v = parseInt(r.reverse().join(''), 2);
  return arr[SIGN] ? -v : v;
};

var _echo = function(arr) {
  if (!arr) return 'undefined';
  var s = arr.concat().reverse().join('');
  return s + ' (' + _value_of(arr) + ')';
};

var _min_max = function(bit) {
  var s1 = [1], s2 = [0];
  while (--bit > 0) {
    s1.unshift(0);
    s2.unshift(1);
  }
  return [ s1, s2 ];
};

/* Entry Point */
jQuery(function($) {

  for (var i = 2; i <= 32; i++) {
    $('select#N1').append('<option value='+i+'>'+i+'</option>');
  }
  $('select#N1').val(16);

  $('#B1').on('click', function() {
    BIT = $('select#N1').val();
    SIGN = BIT - 1;
    var a = $('#T1').val();
    var b = $('#T2').val();
    var ba = _bits(a), bb = _bits(b);
    var b1 = adder(ba, bb);
    var b2 = subtractor(ba, bb);
    var b3 = multiplier(ba, bb);
    var b4 = b != 0 ? divider(ba, bb) : null;
    var b5 = b != 0 ? remainder(ba, bb) : null;
    $('#p0').text(' a : ' + _echo(ba));
    $('#p1').text(' b : ' + _echo(bb));
    $('#p2').text('a+b: ' + _echo(b1));
    $('#p3').text('a-b: ' + _echo(b2));
    $('#p4').text('a*b: ' + _echo(b3));
    $('#p5').text('a/b: ' + _echo(b4));
    $('#p6').text('a%b: ' + _echo(b5));
    var v = _min_max(BIT);
    $('#p7').text('min: ' + _echo(v[0]));
    $('#p8').text('max: ' + _echo(v[1]));
  }).click();

});