Comparing version 0.1.3 to 0.2.0
{ | ||
"name": "uint32", | ||
"version": "0.1.3", | ||
"version": "0.2.0", | ||
"description": "a javascript library for dealing with (bitwise) uint32 operations", | ||
@@ -8,4 +8,4 @@ "homepage": "https://www.github.com/fxa/uint32.js", | ||
"scripts": { | ||
"test": "jshint uint32.js test_uint32.js && mocha --reporter spec test_uint32", | ||
"hint": "jshint uint32.js test_uint32.js" | ||
"test": "jshint uint32.js test_uint32.js && jscs uint32.js test_uint32.js && mocha --reporter spec test_uint32", | ||
"hint": "jshint uint32.js test_uint32.js && jscs uint32.js test_uint32.js" | ||
}, | ||
@@ -26,8 +26,10 @@ "repository": { | ||
"devDependencies": { | ||
"expect.js": "latest", | ||
"mocha": "latest", | ||
"jshint": "latest" | ||
"expect.js": "0.2.0", | ||
"mocha": "1.17.1", | ||
"jshint": "2.4.3", | ||
"jscs": "latest" | ||
}, | ||
"files": [ | ||
"README.md", | ||
"CHANGELOG.md", | ||
"tests.html", | ||
@@ -34,0 +36,0 @@ "test_uint32.js", |
@@ -91,5 +91,2 @@ uint32 | ||
uint32.log2(0xffffffff); // 31 | ||
uint32.multLow(0xffffffff, 0xffffffff); // 1 | ||
uint32.multHigh(0xffffffff, 0xffffffff); // 0xfffffffe | ||
var result = new Uint32Array(2); | ||
@@ -96,0 +93,0 @@ uint32.mult(0xffffffff, 0xffffffff, result); // result -> [0xfffffffe, 0x00000001] |
@@ -16,3 +16,4 @@ /* global describe, it, require, window */ | ||
} | ||
function expectHex(ui32) { | ||
function expectHex (ui32) { | ||
return { | ||
@@ -26,3 +27,3 @@ to: { | ||
} | ||
describe('Creating and Extracting', function () { | ||
@@ -34,3 +35,3 @@ describe('fromBytesBigEndian()', function () { | ||
}); | ||
describe('getByteBigEndian()', function () { | ||
@@ -50,3 +51,3 @@ it('should extract the high byte', function () { | ||
}); | ||
describe('toHex()', function () { | ||
@@ -60,3 +61,3 @@ it('should fill with leading zeros', function () { | ||
}); | ||
describe('toUint32()', function () { | ||
@@ -67,3 +68,3 @@ it('should convert an uint32 value', function () { | ||
it('should convert a negative value', function () { | ||
expect(uint32.toUint32(-1)).to.be(0xffffffff); | ||
expect(uint32.toUint32( -1)).to.be(0xffffffff); | ||
}); | ||
@@ -78,5 +79,5 @@ it('should convert a high value', function () { | ||
}); | ||
describe('Bitwise Logical Operations', function () { | ||
describe('or', function () { | ||
describe('or()', function () { | ||
it('should handle low bits', function () { | ||
@@ -95,4 +96,4 @@ expect(uint32.or(1, 1)).to.be(1); | ||
}); | ||
describe('and', function () { | ||
describe('and()', function () { | ||
it('should handle low bits', function () { | ||
@@ -112,3 +113,3 @@ expect(uint32.and(1, 1)).to.be(1); | ||
describe('xor', function () { | ||
describe('xor()', function () { | ||
it('should xor high bit to off', function () { | ||
@@ -126,4 +127,4 @@ expect(uint32.xor(0x80000000, 0xffffffff)).to.be(0x7fffffff); | ||
}); | ||
describe('not', function () { | ||
describe('not()', function () { | ||
it('should negate 0', function () { | ||
@@ -133,3 +134,3 @@ expect(uint32.not(0)).to.be(0xffffffff); | ||
it('should negate negative values', function () { | ||
expect(uint32.not(-1)).to.be(0); | ||
expect(uint32.not( -1)).to.be(0); | ||
}); | ||
@@ -141,3 +142,3 @@ it('should negate values with high bit set', function () { | ||
}); | ||
describe('Shifting and Rotating', function () { | ||
@@ -158,3 +159,3 @@ describe('shiftLeft()', function () { | ||
}); | ||
describe('rotateLeft()', function () { | ||
@@ -170,3 +171,3 @@ it('should rotate little values', function () { | ||
}); | ||
describe('rotateRight()', function () { | ||
@@ -181,8 +182,8 @@ it('should rotate little values', function () { | ||
}); | ||
}); | ||
}); | ||
}); | ||
describe('Logical Gates', function () { | ||
describe('choose()', function () { | ||
it('should use y, if x flag is set', function () { | ||
@@ -193,3 +194,3 @@ expect(uint32.choose(1, 0, 0)).to.be(0); | ||
expect(uint32.choose(1, 1, 1)).to.be(1); | ||
expect(uint32.choose(0xffffffff, 0, 0)).to.be(0); | ||
@@ -205,3 +206,3 @@ expect(uint32.choose(0xffffffff, 0, 0xffffffff)).to.be(0); | ||
expect(uint32.choose(0, 1, 1)).to.be(1); | ||
expect(uint32.choose(0, 0, 0)).to.be(0); | ||
@@ -241,3 +242,3 @@ expect(uint32.choose(0, 0, 0xffffffff)).to.be(0xffffffff); | ||
describe('Arithmetic', function () { | ||
describe('addMod32', function () { | ||
describe('addMod32()', function () { | ||
it('should add values below 2^32', function () { | ||
@@ -253,3 +254,3 @@ expect(uint32.addMod32(0x40000000, 0x40000000)).to.be(0x80000000); | ||
it('should add negative values', function () { | ||
expect(uint32.addMod32(-1, -1)).to.be(0xfffffffe); | ||
expect(uint32.addMod32( -1, -1)).to.be(0xfffffffe); | ||
}); | ||
@@ -260,5 +261,5 @@ it('should calc mod32', function () { | ||
}); | ||
describe('log2', function () { | ||
describe('log2()', function () { | ||
it('should work for 0', function () { | ||
expect(uint32.log2(0)).to.be(-Infinity); | ||
expect(uint32.log2(0)).to.be( -Infinity); | ||
}); | ||
@@ -282,30 +283,3 @@ it('should work for 1', function () { | ||
}); | ||
describe('multLow', function () { | ||
it('should work, if the product is smaller than 2^52', function () { | ||
expect(uint32.multLow(0x04000000, 0x03ffffff)).to.be(0xfc000000); | ||
}); | ||
it('should work, if the product is 2^52', function () { | ||
expect(uint32.multLow(0x04000000, 0x04000000)).to.be(0); | ||
}); | ||
it('should work, if the product is greater than 2^52', function () { | ||
expect(uint32.multLow(0xff030201, 0xff030201)).to.be(0x0a0a0401); | ||
expect(uint32.multLow(0xffffffff, 0xffffffff)).to.be(0x00000001); | ||
}); | ||
}); | ||
describe('multHigh', function () { | ||
it('should return 0, if the product is less than 2^32', function () { | ||
expect(uint32.multHigh(0xffff, 0xffff)).to.be(0); | ||
}); | ||
it('should work, if the product is smaller than 2^52', function () { | ||
expect(uint32.multHigh(0x04000000, 0x03ffffff)).to.be(0xfffff); | ||
}); | ||
it('should work, if the product is 2^52', function () { | ||
expect(uint32.multHigh(0x04000000, 0x04000000)).to.be(0x00100000); | ||
}); | ||
it('should work, if the product is greater than 2^52', function () { | ||
expect(uint32.multHigh(0xff030201, 0xff030201)).to.be(0xfe06fe07); | ||
expect(uint32.multHigh(0xffffffff, 0xffffffff)).to.be(0xfffffffe); | ||
}); | ||
}); | ||
describe('mult', function () { | ||
describe('mult()', function () { | ||
it('should work, if the product is less than 2^32', function () { | ||
@@ -334,11 +308,22 @@ var result = new Uint32Array(2); | ||
expectHex(result[1]).to.be(0x0a0a0401); | ||
uint32.mult(0xffffffff, 0xffffffff, result); | ||
expect(result[0]).to.be(0xfffffffe); | ||
expect(result[1]).to.be(1); | ||
// (2**15 + 1) ** 2 = 2**30 + 2 * 2**15 + 1 = 0x40 00 00 01 00 00 00 01 | ||
uint32.mult(0x80000001, 0x80000001, result); | ||
expectHex(result[0]).to.be(0x40000001); | ||
expectHex(result[1]).to.be(0x00000001); | ||
}); | ||
it('should not make the rounding error the 0.1.3 version did', function () { | ||
var result = new Uint32Array(2); | ||
uint32.mult(0xfa93896b, 0xa1a9f539, result); | ||
expectHex(result[1]).to.be(0xffffffd3); | ||
expectHex(result[0]).to.be(0x9e3d24d8); | ||
}); | ||
}); | ||
}); | ||
})(); | ||
})(); |
109
uint32.js
@@ -15,3 +15,3 @@ /* jshint bitwise: false */ | ||
// | ||
/** | ||
@@ -31,3 +31,3 @@ * Creates an uint32 from the given bytes in big endian order. | ||
* Returns the byte. | ||
* e.g. when byteNo is 0, the high byte is returned, when byteNo = 3 the low byte is returned. | ||
* e.g. when byteNo is 0, the high byte is returned, when byteNo = 3 the low byte is returned. | ||
* @param {Number} uint32value the source to be extracted | ||
@@ -40,12 +40,15 @@ * @param {Number} byteNo 0-3 the byte number, 0 is the high byte, 3 the low byte | ||
}; | ||
/** | ||
* Returns the bytes as array. | ||
* e.g. when byteNo is 0, the high byte is returned, when byteNo = 3 the low byte is returned. | ||
* @param {Number} uint32value the source to be extracted | ||
* @param {Number} byteNo 0-3 the byte number, 0 is the high byte, 3 the low byte | ||
* @returns {Array} the array [highByte, 2ndHighByte, 3rdHighByte, lowByte] | ||
*/ | ||
exporter.getByteBigsEndian = function (uint32value, byteNo) { | ||
return [exporter.getByteBigEndian(0), exporter.getByteBigEndian(1), exporter.getByteBigEndian(2), exporter.getByteBigEndian(3)]; | ||
exporter.getBytesBigEndian = function (uint32value) { | ||
return [ | ||
exporter.getByteBigEndian(uint32value, 0), | ||
exporter.getByteBigEndian(uint32value, 1), | ||
exporter.getByteBigEndian(uint32value, 2), | ||
exporter.getByteBigEndian(uint32value, 3) | ||
]; | ||
}; | ||
@@ -56,3 +59,3 @@ | ||
* @param {Number} uint32value the uint32 to be stringified | ||
* @param {Number} optionalMinLength the optional (default 8) | ||
* @param {Number} optionalMinLength the optional (default 8) | ||
*/ | ||
@@ -70,5 +73,5 @@ exporter.toHex = function (uint32value, optionalMinLength) { | ||
* Converts a number to an uint32. | ||
* @param {Number} the number to be converted. | ||
* @returns {Number} an uint32 value | ||
*/ | ||
* @param {Number} number the number to be converted. | ||
* @return {Number} an uint32 value | ||
*/ | ||
exporter.toUint32 = function (number) { | ||
@@ -78,8 +81,8 @@ // the shift operator forces js to perform the internal ToUint32 (see ecmascript spec 9.6) | ||
}; | ||
/** | ||
* Returns the part above the uint32 border. | ||
* Depending to the javascript engine, that are the 54-32 = 22 high bits | ||
* @param {Number} the number to extract the high part | ||
* @returns the high part of the number | ||
* @param {Number} number the number to extract the high part | ||
* @return {Number} the high part of the number | ||
*/ | ||
@@ -93,3 +96,3 @@ exporter.highPart = function (number) { | ||
// | ||
/** | ||
@@ -108,3 +111,3 @@ * Returns a bitwise OR operation on two or more values. | ||
}; | ||
/** | ||
@@ -123,3 +126,3 @@ * Returns a bitwise AND operation on two or more values. | ||
}; | ||
/** | ||
@@ -141,8 +144,8 @@ * Returns a bitwise XOR operation on two or more values. | ||
return (~uint32val) >>> 0; | ||
}; | ||
}; | ||
// | ||
// Shifting and Rotating | ||
// | ||
/** | ||
@@ -157,3 +160,3 @@ * Returns the uint32 representation of a << operation. | ||
}; | ||
/** | ||
@@ -168,3 +171,3 @@ * Returns the uint32 representation of a >>> operation. | ||
}; | ||
exporter.rotateLeft = function (uint32val, numBits) { | ||
@@ -175,9 +178,9 @@ return (((uint32val << numBits) >>> 0) | (uint32val >>> (32 - numBits))) >>> 0; | ||
exporter.rotateRight = function (uint32val, numBits) { | ||
return (((uint32val) >>> (numBits)) | ((uint32val) << (32 - numBits)) >>> 0) >>> 0; | ||
return (((uint32val) >>> (numBits)) | ((uint32val) << (32 - numBits)) >>> 0) >>> 0; | ||
}; | ||
// | ||
// Logical Gates | ||
// | ||
/** | ||
@@ -189,3 +192,3 @@ * Bitwise choose bits from y or z, as a bitwise x ? y : z | ||
}; | ||
/** | ||
@@ -198,7 +201,7 @@ * Majority gate for three parameters. Takes bitwise the majority of x, y and z, | ||
}; | ||
// | ||
// Arithmetic | ||
// | ||
/** | ||
@@ -218,4 +221,4 @@ * Adds the given values modulus 2^32. | ||
* Returns the log base 2 of the given value. That is the number of the highest set bit. | ||
* @param uint32val | ||
* @returns {Number} the logarithm base 2, an integer between 0 and 31 | ||
* @param {Number} uint32val the value, the log2 is calculated of | ||
* @return {Number} the logarithm base 2, an integer between 0 and 31 | ||
*/ | ||
@@ -225,8 +228,8 @@ exporter.log2 = function (uint32val) { | ||
}; | ||
/* | ||
/* | ||
// this implementation does the same, looks much funnier, but takes 2 times longer (according to jsperf) ... | ||
var log2_u = new Uint32Array(2); | ||
var log2_d = new Float64Array(log2_u.buffer); | ||
exporter.log2 = function (uint32val) { | ||
@@ -249,32 +252,2 @@ // Ported from http://graphics.stanford.edu/~seander/bithacks.html#IntegerLogIEEE64Float to javascript | ||
/** | ||
* Returns the "low" part of the multiplication. | ||
* @param {Number} factor1 an uint32 | ||
* @param {Number} factor2 an uint32 | ||
* @returns {Number} the low part of the product, that is factor1 * factor2 modulus 2^32 | ||
*/ | ||
exporter.multLow = function (factor1, factor2) { | ||
// We could test with log2(factor1) + log2(factor2) < 52, | ||
// but it is easier to check the product than to check the number of bits of both | ||
var prod = factor1 * factor2; | ||
if (prod <= POW_2_52) { | ||
return prod >>> 0; | ||
} | ||
// a*b mod x can be divided to (a1*b) mod x + (a2*b) mod x with a1+a2=a | ||
// so lets make 2 multiplications with 16 and 32 bits | ||
return ((((factor1 & 0xffff0000) * factor2) >>> 0) + (((factor1 & 0x0000ffff) * factor2) >>> 0)) >>> 0; | ||
}; | ||
/** | ||
* Returns the "high" part of the multiplication. | ||
* @param {Number} factor1 an uint32 | ||
* @param {Number} factor2 an uint32 | ||
* @returns {Number} the high part of the product, that is factor1 * factor2 divided 2^32 without fraction | ||
*/ | ||
exporter.multHigh = function (factor1, factor2) { | ||
var prod = factor1 * factor2; | ||
// the top 52 bits are ok, so the top 32 bits, too | ||
return exporter.highPart(prod); | ||
}; | ||
/** | ||
* Returns the the low and the high uint32 of the multiplication. | ||
@@ -285,12 +258,12 @@ * @param {Number} factor1 an uint32 | ||
* @returns undefined | ||
*/ | ||
*/ | ||
exporter.mult = function (factor1, factor2, resultUint32Array2) { | ||
var high16 = ((factor1 & 0xffff0000) >>> 0) * factor2; | ||
var low16 = (factor1 & 0x0000ffff) * factor2; | ||
resultUint32Array2[0] = ((high16 + low16) / POW_2_32) >>> 0; | ||
// the last >>> 0 is not needed, it is done implicitly by the uin32array | ||
// the addition is dangerous, because the result will be rounded, so the result depends on the lowest bits, which will be cut away! | ||
var carry = ((exporter.toUint32(high16) + exporter.toUint32(low16)) >= POW_2_32) ? 1 : 0; | ||
resultUint32Array2[0] = (exporter.highPart(high16) + exporter.highPart(low16) + carry) >>> 0; | ||
resultUint32Array2[1] = ((high16 >>> 0) + (low16 >>> 0));// >>> 0; | ||
}; | ||
}) ((typeof module !== 'undefined') ? module.exports = {} : window.uint32 = {}); | ||
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
6
28098
4
504
105