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();
});