/**
*
* @source: http://dl5jaf.darc.de/math/binarynotation.js
*
* @licstart The following is the entire license notice for the
* JavaScript code in this page.
*
* Copyright (C) 2014 Johannes Fechner
*
* The JavaScript code in this page is free software: you can
* redistribute it and/or modify it under the terms of the GNU
* General Public License (GNU GPL) as published by the Free Software
* Foundation, either version 3 of the License, or (at your option)
* any later version. The code is distributed WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU GPL for more details.
*
* As additional permission under GNU GPL version 3 section 7, you
* may distribute non-source (e.g., minimized or compacted) forms of
* that code without the copy of the GNU GPL normally required by
* section 4, provided you include this license notice and a URL
* through which recipients can access the Corresponding Source.
*
* The GNU General Public License is available at
* .
*
* @licend The above is the entire license notice
* for the JavaScript code in this page.
*
*/
/*
Author: Johannes Fechner, DL5JAF
E-mail: dl5jaf at darc dot de
Last modified: 2014-03-18
*/
/* The object constructed by the following function represents a binary place value notation of a number with a virtually arbitrary amount of bits.
The binary digits are stored little-endian in the passed Array object aBinary so that the index of a digit equals its corresponding base's exponent. Whereas the bits are saved as boolean values, they are assigned or returned as primitive numbers 0 or 1.
The Array object aBinary which is passed as an argument is accessed directly without copying. If aBinary is empty the object represents zero. */
function BinaryNotation(aBinary) {
/* Empty array is considered as zero.
The property aBinary should be treated as private. */
this.aBinary = aBinary;
/* Create a new object with the same value as this.
return: BinaryNotation object */
this.copy = function() {
var bnCopy = new BinaryNotation([]);
for(var i = 0; i < this.aBinary.length; i++) {
bnCopy.aBinary.push(this.aBinary[i]);
}
return bnCopy;
}
/* Remove leading zeros of this object. [False] is also seen as a leading zero and will be reduced to []. */
this.removeLeadingZeros = function() {
var i = this.aBinary.length - 1;
while(i >= 0 && this.aBinary[i] == 0) {
this.aBinary.pop();
i--;
}
}
/* Get the length as number of bits without leading zeros.
return: Number */
this.length = function() {
/* Ensure that no leading zeros are counted. */
this.removeLeadingZeros();
return this.aBinary.length;
}
/* Test whether this is zero.
return: Boolean */
this.isZero = function() {
/* Ensure that no leading zeros exist. */
this.removeLeadingZeros();
/* Now, aBinary is empty if this value is zero. */
return this.aBinary.length == 0;
}
/* Equality relation.
bnRightValue: BinaryNotation object
return: Boolean */
this.isEqual = function(bnRightValue) {
var i;
/* Ensure that no leading zeros exist. */
this.removeLeadingZeros();
bnRightValue.removeLeadingZeros();
/* Compare the arrays. */
i = this.aBinary.length;
if(i != bnRightValue.aBinary.length) {
return false;
}
while(i-- > 0) {
if(this.aBinary[i] != bnRightValue.aBinary[i]) {
return false;
}
}
return true;
}
/* Get bit at given index as 0 or 1. If index exceeds range, a 0 will be returned.
index: Number
return: Number */
this.getBit = function(index) {
if(0 <= index && index < this.aBinary.length) {
if(this.aBinary[index]) {
return 1;
}
}
return 0;
}
/* Append bit with value 0 or 1 at most significant position.
value: Number (0 or 1) */
this.addMSB = function(value) {
this.aBinary.push(value != 0);
}
/* Insert bit with value 0 or 1 at least significant position.
value: Number (0 or 1) */
this.addLSB = function(value) {
this.aBinary.unshift(value != 0);
}
/* Left shift by n bits (inserting n zeros before LSB), only if this is not zero.
n: Number (non-negative) */
this.leftShift = function(n) {
if(!this.isZero()) {
while(n > 0) {
this.aBinary.unshift(false);
n--;
}
}
}
/* Right shift by n bits (n-times removing LSB), break if value has reached zero.
n: Number (non-negative) */
this.rightShift = function(n) {
while(n > 0 && this.aBinary.length > 0) {
this.aBinary.shift();
n--;
}
}
}