ieee754-buffer
Advanced tools
Comparing version 0.0.2 to 0.1.0
# CHANGELOG | ||
## 0.1.0 (2018-08-04) | ||
- API change: IEEE754Buffer as a class | ||
## 0.0.2 (2018-08-04) | ||
- UMD compatible with IE6+ |
@@ -1,2 +0,2 @@ | ||
// Type definitions for ieee754-buffer 0.0.2 | ||
// Type definitions for ieee754-buffer 0.1.0 | ||
// Project: https://github.com/rochars/ieee754-buffer | ||
@@ -6,35 +6,34 @@ // Definitions by: Rafael da Silva Rocha <https://github.com/rochars> | ||
/** | ||
* Pack a IEEE 754 floating point number. | ||
* Derived from typedarray.js by Linden Research, MIT License. | ||
* @see https://bitbucket.org/lindenlab/llsd/raw/7d2646cd3f9b4c806e73aebc4b32bd81e4047fdc/js/typedarray.js | ||
* @param {!Uint8Array|!Array<number>} buffer The buffer. | ||
* @param {number} index The index to write on the buffer. | ||
* @param {number} num The number. | ||
* @param {number} ebits The number of bits of the exponent. | ||
* @param {number} fbits The number of bits of the fraction. | ||
* @return {number} The next index to write on the buffer. | ||
*/ | ||
export function pack( | ||
buffer: Uint8Array|number[], | ||
index: number, | ||
num: number, | ||
ebits: number, | ||
fbits: number): number; | ||
export {IEEE754Buffer}; | ||
/** | ||
* Unpack a IEEE 754 floating point number. | ||
* Derived from IEEE754 by DeNA Co., Ltd., MIT License. | ||
* Adapted to handle NaN. Should port the solution to the original repo. | ||
* @see https://github.com/kazuho/ieee754.js/blob/master/ieee754.js | ||
* @param {!Uint8Array|!Array<number>} buffer The buffer. | ||
* @param {number} index The index to read from the buffer. | ||
* @param {number} ebits The number of bits of the exponent. | ||
* @param {number} fbits The number of bits of the fraction. | ||
* @return {number} The floating point number. | ||
*/ | ||
export function unpack( | ||
buffer: Uint8Array|number[], | ||
index: number, | ||
ebits: number, | ||
fbits: number): number; | ||
declare class IEEE754Buffer { | ||
/** | ||
* Pack a IEEE 754 floating point number. | ||
* @param {number} ebits The exponent bits. | ||
* @param {number} fbits The fraction bits. | ||
*/ | ||
constructor(ebits, fbits); | ||
/** | ||
* Pack a IEEE 754 floating point number. | ||
* @param {!Uint8Array|!Array<number>} buffer The buffer. | ||
* @param {number} index The index to write on the buffer. | ||
* @param {number} num The number. | ||
* @return {number} The next index to write on the buffer. | ||
*/ | ||
pack( | ||
buffer: Uint8Array|number[], | ||
index: number, | ||
num: number): number; | ||
/** | ||
* Unpack a IEEE 754 floating point number. | ||
* @param {!Uint8Array|!Array<number>} buffer The buffer. | ||
* @param {number} index The index to read from the buffer. | ||
* @return {number} The floating point number. | ||
*/ | ||
unpack( | ||
buffer: Uint8Array|number[], | ||
index: number): number; | ||
} |
@@ -28,165 +28,178 @@ /* | ||
/** | ||
* @fileoverview Functions to pack and unpack IEEE 754 floating point numbers. | ||
* @fileoverview Encode and decode IEEE 754 floating point numbers. | ||
* @see https://github.com/rochars/ieee754-buffer | ||
* @see https://bitbucket.org/lindenlab/llsd/raw/7d2646cd3f9b4c806e73aebc4b32bd81e4047fdc/js/typedarray.js | ||
* @see https://github.com/kazuho/ieee754.js/blob/master/ieee754.js | ||
*/ | ||
/** @module ieee754Buffer */ | ||
/** | ||
* @module IEEE754Buffer | ||
* @ignore | ||
*/ | ||
/** | ||
* Pack a IEEE 754 floating point number. | ||
* Derived from typedarray.js by Linden Research, MIT License. | ||
* @see https://bitbucket.org/lindenlab/llsd/raw/7d2646cd3f9b4c806e73aebc4b32bd81e4047fdc/js/typedarray.js | ||
* @param {!Uint8Array|!Array<number>} buffer The buffer. | ||
* @param {number} index The index to write on the buffer. | ||
* @param {number} num The number. | ||
* @param {number} ebits The number of bits of the exponent. | ||
* @param {number} fbits The number of bits of the fraction. | ||
* @return {number} The next index to write on the buffer. | ||
* A class to encode and decode IEEE 754 floating-point numbers. | ||
*/ | ||
export function pack(buffer, index, num, ebits, fbits) { | ||
/** @type {number} */ | ||
let bias = (1 << (ebits - 1)) - 1; | ||
// Round overflows | ||
if (Math.abs(num) > Math.pow(2, bias + 1) - ((ebits + fbits) * 2)) { | ||
num = num < 0 ? -Infinity : Infinity; | ||
export class IEEE754Buffer { | ||
/** | ||
* Pack a IEEE 754 floating point number. | ||
* @param {number} ebits The exponent bits. | ||
* @param {number} fbits The fraction bits. | ||
*/ | ||
constructor(ebits, fbits) { | ||
this.ebits = ebits; | ||
this.fbits = fbits; | ||
this.bias = (1 << (ebits - 1)) - 1; | ||
this.numBytes = Math.ceil((ebits + fbits) / 8); | ||
this.biasP2 = Math.pow(2, this.bias + 1); | ||
this.ebitsFbits = (ebits + fbits); | ||
this.fbias = Math.pow(2, -(8 * this.numBytes - 1 - ebits)); | ||
} | ||
/** | ||
* sign, need this to handle negative zero | ||
* @see http://cwestblog.com/2014/02/25/javascript-testing-for-negative-zero/ | ||
* @type {number} | ||
* Pack a IEEE 754 floating point number. | ||
* @param {!Uint8Array|!Array<number>} buffer The buffer. | ||
* @param {number} index The index to write on the buffer. | ||
* @param {number} num The number. | ||
* @return {number} The next index to write on the buffer. | ||
*/ | ||
let sign = (((num = +num) || 1 / num) < 0) ? 1 : num < 0 ? 1 : 0; | ||
num = Math.abs(num); | ||
/** @type {number} */ | ||
let exp = Math.min(Math.floor(Math.log(num) / Math.LN2), 1023); | ||
/** @type {number} */ | ||
let fraction = roundToEven(num / Math.pow(2, exp) * Math.pow(2, fbits)); | ||
// NaN | ||
if (num !== num) { | ||
fraction = Math.pow(2, fbits - 1); | ||
exp = (1 << ebits) - 1; | ||
// Number | ||
} else if (num !== 0) { | ||
if (num >= Math.pow(2, 1 - bias)) { | ||
if (fraction / Math.pow(2, fbits) >= 2) { | ||
exp = exp + 1; | ||
fraction = 1; | ||
} | ||
// Overflow | ||
if (exp > bias) { | ||
exp = (1 << ebits) - 1; | ||
fraction = 0; | ||
pack(buffer, index, num) { | ||
// Round overflows | ||
if (Math.abs(num) > this.biasP2 - (this.ebitsFbits * 2)) { | ||
num = num < 0 ? -Infinity : Infinity; | ||
} | ||
/** | ||
* sign, need this to handle negative zero | ||
* @see http://cwestblog.com/2014/02/25/javascript-testing-for-negative-zero/ | ||
* @type {number} | ||
*/ | ||
let sign = (((num = +num) || 1 / num) < 0) ? 1 : num < 0 ? 1 : 0; | ||
num = Math.abs(num); | ||
/** @type {number} */ | ||
let exp = Math.min(Math.floor(Math.log(num) / Math.LN2), 1023); | ||
/** @type {number} */ | ||
let fraction = this.roundToEven(num / Math.pow(2, exp) * Math.pow(2, this.fbits)); | ||
// NaN | ||
if (num !== num) { | ||
fraction = Math.pow(2, this.fbits - 1); | ||
exp = (1 << this.ebits) - 1; | ||
// Number | ||
} else if (num !== 0) { | ||
if (num >= Math.pow(2, 1 - this.bias)) { | ||
if (fraction / Math.pow(2, this.fbits) >= 2) { | ||
exp = exp + 1; | ||
fraction = 1; | ||
} | ||
// Overflow | ||
if (exp > this.bias) { | ||
exp = (1 << this.ebits) - 1; | ||
fraction = 0; | ||
} else { | ||
exp = exp + this.bias; | ||
fraction = this.roundToEven(fraction) - Math.pow(2, this.fbits); | ||
} | ||
} else { | ||
exp = exp + bias; | ||
fraction = roundToEven(fraction) - Math.pow(2, fbits); | ||
fraction = this.roundToEven(num / Math.pow(2, 1 - this.bias - this.fbits)); | ||
exp = 0; | ||
} | ||
} | ||
return this.packFloatBits_(buffer, index, sign, exp, fraction); | ||
} | ||
/** | ||
* Unpack a IEEE 754 floating point number. | ||
* Derived from IEEE754 by DeNA Co., Ltd., MIT License. | ||
* Adapted to handle NaN. Should port the solution to the original repo. | ||
* @param {!Uint8Array|!Array<number>} buffer The buffer. | ||
* @param {number} index The index to read from the buffer. | ||
* @return {number} The floating point number. | ||
*/ | ||
unpack(buffer, index) { | ||
/** @type {number} */ | ||
let eMax = (1 << this.ebits) - 1; | ||
/** @type {number} */ | ||
let significand; | ||
/** @type {string} */ | ||
let leftBits = ""; | ||
for (let i = this.numBytes - 1; i >= 0 ; i--) { | ||
/** @type {string} */ | ||
let t = buffer[i + index].toString(2); | ||
leftBits += "00000000".substring(t.length) + t; | ||
} | ||
/** @type {number} */ | ||
let sign = leftBits.charAt(0) == "1" ? -1 : 1; | ||
leftBits = leftBits.substring(1); | ||
/** @type {number} */ | ||
let exponent = parseInt(leftBits.substring(0, this.ebits), 2); | ||
leftBits = leftBits.substring(this.ebits); | ||
if (exponent == eMax) { | ||
if (parseInt(leftBits, 2) !== 0) { | ||
return NaN; | ||
} | ||
return sign * Infinity; | ||
} else if (exponent === 0) { | ||
exponent += 1; | ||
significand = parseInt(leftBits, 2); | ||
} else { | ||
fraction = roundToEven(num / Math.pow(2, 1 - bias - fbits)); | ||
exp = 0; | ||
} | ||
significand = parseInt("1" + leftBits, 2); | ||
} | ||
return sign * significand * this.fbias * Math.pow(2, exponent - this.bias); | ||
} | ||
return packFloatBits_(buffer, index, ebits, fbits, sign, exp, fraction); | ||
} | ||
/** | ||
* Unpack a IEEE 754 floating point number. | ||
* Derived from IEEE754 by DeNA Co., Ltd., MIT License. | ||
* Adapted to handle NaN. Should port the solution to the original repo. | ||
* @see https://github.com/kazuho/ieee754.js/blob/master/ieee754.js | ||
* @param {!Uint8Array|!Array<number>} buffer The buffer. | ||
* @param {number} index The index to read from the buffer. | ||
* @param {number} ebits The number of bits of the exponent. | ||
* @param {number} fbits The number of bits of the fraction. | ||
* @return {number} The floating point number. | ||
*/ | ||
export function unpack(buffer, index, ebits, fbits) { | ||
let exponentBias = (1 << (ebits - 1)) - 1; | ||
let numBytes = Math.ceil((ebits + fbits) / 8); | ||
/** @type {number} */ | ||
let eMax = (1 << ebits) - 1; | ||
/** @type {number} */ | ||
let bias = Math.pow(2, -(8 * numBytes - 1 - ebits)); | ||
/** @type {number} */ | ||
let significand; | ||
/** @type {string} */ | ||
let leftBits = ""; | ||
for (let i = numBytes - 1; i >= 0 ; i--) { | ||
/** | ||
* Pack a IEEE754 from its sign, exponent and fraction bits | ||
* and place it in a byte buffer. | ||
* @param {!Uint8Array|!Array<number>} buffer The byte buffer to write to. | ||
* @param {number} index The buffer index to write. | ||
* @param {number} ebits The number of bits of the exponent. | ||
* @param {number} fbits The number of bits of the fraction. | ||
* @param {number} sign The sign. | ||
* @param {number} exp the exponent. | ||
* @param {number} fraction The fraction. | ||
* @return {number} | ||
* @private | ||
*/ | ||
packFloatBits_(buffer, index, sign, exp, fraction) { | ||
/** @type {!Array<number>} */ | ||
let bits = []; | ||
// the sign | ||
bits.push(sign); | ||
// the exponent | ||
for (let i = this.ebits; i > 0; i -= 1) { | ||
bits[i] = (exp % 2 ? 1 : 0); | ||
exp = Math.floor(exp / 2); | ||
} | ||
// the fraction | ||
let len = bits.length; | ||
for (let i = this.fbits; i > 0; i -= 1) { | ||
bits[len + i] = (fraction % 2 ? 1 : 0); | ||
fraction = Math.floor(fraction / 2); | ||
} | ||
// pack as bytes | ||
/** @type {string} */ | ||
let t = buffer[i + index].toString(2); | ||
leftBits += "00000000".substring(t.length) + t; | ||
} | ||
/** @type {number} */ | ||
let sign = leftBits.charAt(0) == "1" ? -1 : 1; | ||
leftBits = leftBits.substring(1); | ||
/** @type {number} */ | ||
let exponent = parseInt(leftBits.substring(0, ebits), 2); | ||
leftBits = leftBits.substring(ebits); | ||
if (exponent == eMax) { | ||
if (parseInt(leftBits, 2) !== 0) { | ||
return NaN; | ||
let str = bits.join(''); | ||
/** @type {number} */ | ||
let numBytes = this.numBytes + index - 1; | ||
/** @type {number} */ | ||
let k = index; | ||
while (numBytes >= index) { | ||
buffer[numBytes] = parseInt(str.substring(0, 8), 2); | ||
str = str.substring(8); | ||
numBytes--; | ||
k++; | ||
} | ||
return sign * Infinity; | ||
} else if (exponent === 0) { | ||
exponent += 1; | ||
significand = parseInt(leftBits, 2); | ||
} else { | ||
significand = parseInt("1" + leftBits, 2); | ||
return k; | ||
} | ||
return sign * significand * bias * Math.pow(2, exponent - exponentBias); | ||
} | ||
/** | ||
* Pack a IEEE754 from its sign, exponent and fraction bits | ||
* and place it in a byte buffer. | ||
* @param {!Uint8Array|!Array<number>} buffer The byte buffer to write to. | ||
* @param {number} index The buffer index to write. | ||
* @param {number} ebits The number of bits of the exponent. | ||
* @param {number} fbits The number of bits of the fraction. | ||
* @param {number} sign The sign. | ||
* @param {number} exp the exponent. | ||
* @param {number} fraction The fraction. | ||
* @return {number} | ||
* @private | ||
*/ | ||
function packFloatBits_(buffer, index, ebits, fbits, sign, exp, fraction) { | ||
/** @type {!Array<number>} */ | ||
let bits = []; | ||
// the sign | ||
bits.push(sign); | ||
// the exponent | ||
for (let i = ebits; i > 0; i -= 1) { | ||
bits[i] = (exp % 2 ? 1 : 0); | ||
exp = Math.floor(exp / 2); | ||
roundToEven(n) { | ||
var w = Math.floor(n), f = n - w; | ||
if (f < 0.5) { | ||
return w; | ||
} | ||
if (f > 0.5) { | ||
return w + 1; | ||
} | ||
return w % 2 ? w + 1 : w; | ||
} | ||
// the fraction | ||
let len = bits.length; | ||
for (let i = fbits; i > 0; i -= 1) { | ||
bits[len + i] = (fraction % 2 ? 1 : 0); | ||
fraction = Math.floor(fraction / 2); | ||
} | ||
// pack as bytes | ||
/** @type {string} */ | ||
let str = bits.join(''); | ||
/** @type {number} */ | ||
let numBytes = Math.floor((ebits + fbits + 1) / 8) + index - 1; | ||
/** @type {number} */ | ||
let k = index; | ||
while (numBytes >= index) { | ||
buffer[numBytes] = parseInt(str.substring(0, 8), 2); | ||
str = str.substring(8); | ||
numBytes--; | ||
k++; | ||
} | ||
return k; | ||
} | ||
function roundToEven(n) { | ||
var w = Math.floor(n), f = n - w; | ||
if (f < 0.5) { | ||
return w; | ||
} | ||
if (f > 0.5) { | ||
return w + 1; | ||
} | ||
return w % 2 ? w + 1 : w; | ||
} | ||
} |
@@ -1,3 +0,27 @@ | ||
;(function (global, factory) {typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :typeof define === 'function' && define.amd ? define(factory) :(global.ieee754Buffer = factory());}(this, (function () { | ||
var ieee754Buffer = (function (exports) { | ||
;(function (global, factory) {typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :typeof define === 'function' && define.amd ? define(factory) :(global.IEEE754Buffer = factory());}(this, (function () { | ||
var IEEE754Buffer = (function (exports) { | ||
var classCallCheck = function (instance, Constructor) { | ||
if (!(instance instanceof Constructor)) { | ||
throw new TypeError("Cannot call a class as a function"); | ||
} | ||
}; | ||
var createClass = function () { | ||
function defineProperties(target, props) { | ||
for (var i = 0; i < props.length; i++) { | ||
var descriptor = props[i]; | ||
descriptor.enumerable = descriptor.enumerable || false; | ||
descriptor.configurable = true; | ||
if ("value" in descriptor) descriptor.writable = true; | ||
Object.defineProperty(target, descriptor.key, descriptor); | ||
} | ||
} | ||
return function (Constructor, protoProps, staticProps) { | ||
if (protoProps) defineProperties(Constructor.prototype, protoProps); | ||
if (staticProps) defineProperties(Constructor, staticProps); | ||
return Constructor; | ||
}; | ||
}(); | ||
/* | ||
@@ -30,170 +54,197 @@ * Copyright (c) 2018 Rafael da Silva Rocha. | ||
/** | ||
* @fileoverview Functions to pack and unpack IEEE 754 floating point numbers. | ||
* @fileoverview Encode and decode IEEE 754 floating point numbers. | ||
* @see https://github.com/rochars/ieee754-buffer | ||
* @see https://bitbucket.org/lindenlab/llsd/raw/7d2646cd3f9b4c806e73aebc4b32bd81e4047fdc/js/typedarray.js | ||
* @see https://github.com/kazuho/ieee754.js/blob/master/ieee754.js | ||
*/ | ||
/** @module ieee754Buffer */ | ||
/** | ||
* @module IEEE754Buffer | ||
* @ignore | ||
*/ | ||
/** | ||
* Pack a IEEE 754 floating point number. | ||
* Derived from typedarray.js by Linden Research, MIT License. | ||
* @see https://bitbucket.org/lindenlab/llsd/raw/7d2646cd3f9b4c806e73aebc4b32bd81e4047fdc/js/typedarray.js | ||
* @param {!Uint8Array|!Array<number>} buffer The buffer. | ||
* @param {number} index The index to write on the buffer. | ||
* @param {number} num The number. | ||
* @param {number} ebits The number of bits of the exponent. | ||
* @param {number} fbits The number of bits of the fraction. | ||
* @return {number} The next index to write on the buffer. | ||
* A class to encode and decode IEEE 754 floating-point numbers. | ||
*/ | ||
function pack(buffer, index, num, ebits, fbits) { | ||
/** @type {number} */ | ||
var bias = (1 << ebits - 1) - 1; | ||
// Round overflows | ||
if (Math.abs(num) > Math.pow(2, bias + 1) - (ebits + fbits) * 2) { | ||
num = num < 0 ? -Infinity : Infinity; | ||
var IEEE754Buffer = function () { | ||
/** | ||
* Pack a IEEE 754 floating point number. | ||
* @param {number} ebits The exponent bits. | ||
* @param {number} fbits The fraction bits. | ||
*/ | ||
function IEEE754Buffer(ebits, fbits) { | ||
classCallCheck(this, IEEE754Buffer); | ||
this.ebits = ebits; | ||
this.fbits = fbits; | ||
this.bias = (1 << ebits - 1) - 1; | ||
this.numBytes = Math.ceil((ebits + fbits) / 8); | ||
this.biasP2 = Math.pow(2, this.bias + 1); | ||
this.ebitsFbits = ebits + fbits; | ||
this.fbias = Math.pow(2, -(8 * this.numBytes - 1 - ebits)); | ||
} | ||
/** | ||
* sign, need this to handle negative zero | ||
* @see http://cwestblog.com/2014/02/25/javascript-testing-for-negative-zero/ | ||
* @type {number} | ||
* Pack a IEEE 754 floating point number. | ||
* @param {!Uint8Array|!Array<number>} buffer The buffer. | ||
* @param {number} index The index to write on the buffer. | ||
* @param {number} num The number. | ||
* @return {number} The next index to write on the buffer. | ||
*/ | ||
var sign = ((num = +num) || 1 / num) < 0 ? 1 : num < 0 ? 1 : 0; | ||
num = Math.abs(num); | ||
/** @type {number} */ | ||
var exp = Math.min(Math.floor(Math.log(num) / Math.LN2), 1023); | ||
/** @type {number} */ | ||
var fraction = roundToEven(num / Math.pow(2, exp) * Math.pow(2, fbits)); | ||
// NaN | ||
if (num !== num) { | ||
fraction = Math.pow(2, fbits - 1); | ||
exp = (1 << ebits) - 1; | ||
// Number | ||
} else if (num !== 0) { | ||
if (num >= Math.pow(2, 1 - bias)) { | ||
if (fraction / Math.pow(2, fbits) >= 2) { | ||
exp = exp + 1; | ||
fraction = 1; | ||
createClass(IEEE754Buffer, [{ | ||
key: "pack", | ||
value: function pack(buffer, index, num) { | ||
// Round overflows | ||
if (Math.abs(num) > this.biasP2 - this.ebitsFbits * 2) { | ||
num = num < 0 ? -Infinity : Infinity; | ||
} | ||
// Overflow | ||
if (exp > bias) { | ||
exp = (1 << ebits) - 1; | ||
fraction = 0; | ||
} else { | ||
exp = exp + bias; | ||
fraction = roundToEven(fraction) - Math.pow(2, fbits); | ||
/** | ||
* sign, need this to handle negative zero | ||
* @see http://cwestblog.com/2014/02/25/javascript-testing-for-negative-zero/ | ||
* @type {number} | ||
*/ | ||
var sign = ((num = +num) || 1 / num) < 0 ? 1 : num < 0 ? 1 : 0; | ||
num = Math.abs(num); | ||
/** @type {number} */ | ||
var exp = Math.min(Math.floor(Math.log(num) / Math.LN2), 1023); | ||
/** @type {number} */ | ||
var fraction = this.roundToEven(num / Math.pow(2, exp) * Math.pow(2, this.fbits)); | ||
// NaN | ||
if (num !== num) { | ||
fraction = Math.pow(2, this.fbits - 1); | ||
exp = (1 << this.ebits) - 1; | ||
// Number | ||
} else if (num !== 0) { | ||
if (num >= Math.pow(2, 1 - this.bias)) { | ||
if (fraction / Math.pow(2, this.fbits) >= 2) { | ||
exp = exp + 1; | ||
fraction = 1; | ||
} | ||
// Overflow | ||
if (exp > this.bias) { | ||
exp = (1 << this.ebits) - 1; | ||
fraction = 0; | ||
} else { | ||
exp = exp + this.bias; | ||
fraction = this.roundToEven(fraction) - Math.pow(2, this.fbits); | ||
} | ||
} else { | ||
fraction = this.roundToEven(num / Math.pow(2, 1 - this.bias - this.fbits)); | ||
exp = 0; | ||
} | ||
} | ||
} else { | ||
fraction = roundToEven(num / Math.pow(2, 1 - bias - fbits)); | ||
exp = 0; | ||
return this.packFloatBits_(buffer, index, sign, exp, fraction); | ||
} | ||
} | ||
return packFloatBits_(buffer, index, ebits, fbits, sign, exp, fraction); | ||
} | ||
/** | ||
* Unpack a IEEE 754 floating point number. | ||
* Derived from IEEE754 by DeNA Co., Ltd., MIT License. | ||
* Adapted to handle NaN. Should port the solution to the original repo. | ||
* @see https://github.com/kazuho/ieee754.js/blob/master/ieee754.js | ||
* @param {!Uint8Array|!Array<number>} buffer The buffer. | ||
* @param {number} index The index to read from the buffer. | ||
* @param {number} ebits The number of bits of the exponent. | ||
* @param {number} fbits The number of bits of the fraction. | ||
* @return {number} The floating point number. | ||
*/ | ||
function unpack(buffer, index, ebits, fbits) { | ||
var exponentBias = (1 << ebits - 1) - 1; | ||
var numBytes = Math.ceil((ebits + fbits) / 8); | ||
/** @type {number} */ | ||
var eMax = (1 << ebits) - 1; | ||
/** @type {number} */ | ||
var bias = Math.pow(2, -(8 * numBytes - 1 - ebits)); | ||
/** @type {number} */ | ||
var significand = void 0; | ||
/** @type {string} */ | ||
var leftBits = ""; | ||
for (var i = numBytes - 1; i >= 0; i--) { | ||
/** @type {string} */ | ||
var t = buffer[i + index].toString(2); | ||
leftBits += "00000000".substring(t.length) + t; | ||
} | ||
/** @type {number} */ | ||
var sign = leftBits.charAt(0) == "1" ? -1 : 1; | ||
leftBits = leftBits.substring(1); | ||
/** @type {number} */ | ||
var exponent = parseInt(leftBits.substring(0, ebits), 2); | ||
leftBits = leftBits.substring(ebits); | ||
if (exponent == eMax) { | ||
if (parseInt(leftBits, 2) !== 0) { | ||
return NaN; | ||
/** | ||
* Unpack a IEEE 754 floating point number. | ||
* Derived from IEEE754 by DeNA Co., Ltd., MIT License. | ||
* Adapted to handle NaN. Should port the solution to the original repo. | ||
* @param {!Uint8Array|!Array<number>} buffer The buffer. | ||
* @param {number} index The index to read from the buffer. | ||
* @return {number} The floating point number. | ||
*/ | ||
}, { | ||
key: "unpack", | ||
value: function unpack(buffer, index) { | ||
/** @type {number} */ | ||
var eMax = (1 << this.ebits) - 1; | ||
/** @type {number} */ | ||
var significand = void 0; | ||
/** @type {string} */ | ||
var leftBits = ""; | ||
for (var i = this.numBytes - 1; i >= 0; i--) { | ||
/** @type {string} */ | ||
var t = buffer[i + index].toString(2); | ||
leftBits += "00000000".substring(t.length) + t; | ||
} | ||
/** @type {number} */ | ||
var sign = leftBits.charAt(0) == "1" ? -1 : 1; | ||
leftBits = leftBits.substring(1); | ||
/** @type {number} */ | ||
var exponent = parseInt(leftBits.substring(0, this.ebits), 2); | ||
leftBits = leftBits.substring(this.ebits); | ||
if (exponent == eMax) { | ||
if (parseInt(leftBits, 2) !== 0) { | ||
return NaN; | ||
} | ||
return sign * Infinity; | ||
} else if (exponent === 0) { | ||
exponent += 1; | ||
significand = parseInt(leftBits, 2); | ||
} else { | ||
significand = parseInt("1" + leftBits, 2); | ||
} | ||
return sign * significand * this.fbias * Math.pow(2, exponent - this.bias); | ||
} | ||
return sign * Infinity; | ||
} else if (exponent === 0) { | ||
exponent += 1; | ||
significand = parseInt(leftBits, 2); | ||
} else { | ||
significand = parseInt("1" + leftBits, 2); | ||
} | ||
return sign * significand * bias * Math.pow(2, exponent - exponentBias); | ||
} | ||
/** | ||
* Pack a IEEE754 from its sign, exponent and fraction bits | ||
* and place it in a byte buffer. | ||
* @param {!Uint8Array|!Array<number>} buffer The byte buffer to write to. | ||
* @param {number} index The buffer index to write. | ||
* @param {number} ebits The number of bits of the exponent. | ||
* @param {number} fbits The number of bits of the fraction. | ||
* @param {number} sign The sign. | ||
* @param {number} exp the exponent. | ||
* @param {number} fraction The fraction. | ||
* @return {number} | ||
* @private | ||
*/ | ||
function packFloatBits_(buffer, index, ebits, fbits, sign, exp, fraction) { | ||
/** @type {!Array<number>} */ | ||
var bits = []; | ||
// the sign | ||
bits.push(sign); | ||
// the exponent | ||
for (var i = ebits; i > 0; i -= 1) { | ||
bits[i] = exp % 2 ? 1 : 0; | ||
exp = Math.floor(exp / 2); | ||
} | ||
// the fraction | ||
var len = bits.length; | ||
for (var _i = fbits; _i > 0; _i -= 1) { | ||
bits[len + _i] = fraction % 2 ? 1 : 0; | ||
fraction = Math.floor(fraction / 2); | ||
} | ||
// pack as bytes | ||
/** @type {string} */ | ||
var str = bits.join(''); | ||
/** @type {number} */ | ||
var numBytes = Math.floor((ebits + fbits + 1) / 8) + index - 1; | ||
/** @type {number} */ | ||
var k = index; | ||
while (numBytes >= index) { | ||
buffer[numBytes] = parseInt(str.substring(0, 8), 2); | ||
str = str.substring(8); | ||
numBytes--; | ||
k++; | ||
} | ||
return k; | ||
} | ||
/** | ||
* Pack a IEEE754 from its sign, exponent and fraction bits | ||
* and place it in a byte buffer. | ||
* @param {!Uint8Array|!Array<number>} buffer The byte buffer to write to. | ||
* @param {number} index The buffer index to write. | ||
* @param {number} ebits The number of bits of the exponent. | ||
* @param {number} fbits The number of bits of the fraction. | ||
* @param {number} sign The sign. | ||
* @param {number} exp the exponent. | ||
* @param {number} fraction The fraction. | ||
* @return {number} | ||
* @private | ||
*/ | ||
function roundToEven(n) { | ||
var w = Math.floor(n), | ||
f = n - w; | ||
if (f < 0.5) { | ||
return w; | ||
} | ||
if (f > 0.5) { | ||
return w + 1; | ||
} | ||
return w % 2 ? w + 1 : w; | ||
} | ||
}, { | ||
key: "packFloatBits_", | ||
value: function packFloatBits_(buffer, index, sign, exp, fraction) { | ||
/** @type {!Array<number>} */ | ||
var bits = []; | ||
// the sign | ||
bits.push(sign); | ||
// the exponent | ||
for (var i = this.ebits; i > 0; i -= 1) { | ||
bits[i] = exp % 2 ? 1 : 0; | ||
exp = Math.floor(exp / 2); | ||
} | ||
// the fraction | ||
var len = bits.length; | ||
for (var _i = this.fbits; _i > 0; _i -= 1) { | ||
bits[len + _i] = fraction % 2 ? 1 : 0; | ||
fraction = Math.floor(fraction / 2); | ||
} | ||
// pack as bytes | ||
/** @type {string} */ | ||
var str = bits.join(''); | ||
/** @type {number} */ | ||
var numBytes = this.numBytes + index - 1; | ||
/** @type {number} */ | ||
var k = index; | ||
while (numBytes >= index) { | ||
buffer[numBytes] = parseInt(str.substring(0, 8), 2); | ||
str = str.substring(8); | ||
numBytes--; | ||
k++; | ||
} | ||
return k; | ||
} | ||
}, { | ||
key: "roundToEven", | ||
value: function roundToEven(n) { | ||
var w = Math.floor(n), | ||
f = n - w; | ||
if (f < 0.5) { | ||
return w; | ||
} | ||
if (f > 0.5) { | ||
return w + 1; | ||
} | ||
return w % 2 ? w + 1 : w; | ||
} | ||
}]); | ||
return IEEE754Buffer; | ||
}(); | ||
exports.pack = pack; | ||
exports.unpack = unpack; | ||
exports.IEEE754Buffer = IEEE754Buffer; | ||
@@ -203,2 +254,2 @@ return exports; | ||
}({})); | ||
return ieee754Buffer;}))); | ||
return IEEE754Buffer;}))); |
{ | ||
"name": "ieee754-buffer", | ||
"version": "0.0.2", | ||
"description": "Encode and decode IEEE 754 floating point numbers.", | ||
"version": "0.1.0", | ||
"description": "A class to encode and decode IEEE 754 floating point numbers.", | ||
"homepage": "https://github.com/rochars/ieee754-buffer", | ||
@@ -43,7 +43,4 @@ "author": "Rafael da Silva Rocha <rocha.rafaelsilva@gmail.com>", | ||
}, | ||
"directories": { | ||
"externs": "externs" | ||
}, | ||
"directories": {}, | ||
"files": [ | ||
"externs", | ||
"ieee754-buffer.js", | ||
@@ -57,3 +54,3 @@ "ieee754-buffer.d.ts", | ||
"scripts": { | ||
"lint": "jshint ieee754-buffer.js externs test/src", | ||
"lint": "jshint ieee754-buffer.js test/src", | ||
"test": "nyc ./node_modules/mocha/bin/_mocha test/src --recursive -R dot", | ||
@@ -60,0 +57,0 @@ "test-umd": "node ./node_modules/mocha/bin/_mocha test/src --umd --recursive -R dot", |
@@ -32,4 +32,5 @@ # ieee754-buffer | ||
<script> | ||
let packer = new IEEE754Buffer.IEEE754Buffer(8, 23); | ||
var buffer = []; | ||
ieee754Buffer.pack(buffer, 0, 3.1415927410, 8, 23); | ||
packer.pack(buffer, 0, 3.1415927410); | ||
console.log(buffer); | ||
@@ -56,21 +57,14 @@ </script> | ||
### Node | ||
**Import ieee754Buffer from ieee754-buffer**: | ||
**Import IEEE754Buffer from ieee754-buffer**: | ||
```javascript | ||
import * as ieee754Buffer from 'ieee754-buffer'; | ||
import {IEEE754Buffer} from 'ieee754-buffer'; | ||
let packer = new IEEE754Buffer(8, 23); | ||
let buffer = Uint8Array(4); | ||
ieee754Buffer.pack(buffer, 0, 3.1415927410, 8, 23); | ||
packer.pack(buffer, 0, 3.1415927410); | ||
console.log(buffer); | ||
``` | ||
Or **import** just what you need: | ||
```javascript | ||
import {pack, unpack} from 'ieee754-buffer'; | ||
let buffer = []; // Use arrays or typed arrays | ||
pack(buffer, 0, 3.1415927410, 8, 23) | ||
console.log(buffer); | ||
``` | ||
Or **require**: | ||
```javascript | ||
const ieee754Buffer = require('ieee754-buffer'); | ||
const IEEE754Buffer = require('ieee754-buffer').IEEE754Buffer; | ||
``` | ||
@@ -87,27 +81,31 @@ | ||
```javascript | ||
/** | ||
* Pack a IEEE 754 floating point number. | ||
* Derived from typedarray.js by Linden Research, MIT License. | ||
* @see https://bitbucket.org/lindenlab/llsd/raw/7d2646cd3f9b4c806e73aebc4b32bd81e4047fdc/js/typedarray.js | ||
* @param {!Uint8Array|!Array<number>} buffer The buffer. | ||
* @param {number} index The index to write on the buffer. | ||
* @param {number} num The number. | ||
* @param {number} ebits The number of bits of the exponent. | ||
* @param {number} fbits The number of bits of the fraction. | ||
* @return {number} The next index to write on the buffer. | ||
*/ | ||
function pack(buffer, index, num, ebits, fbits) {} | ||
/** | ||
* Unpack a IEEE 754 floating point number. | ||
* Derived from IEEE754 by DeNA Co., Ltd., MIT License. | ||
* Adapted to handle NaN. Should port the solution to the original repo. | ||
* @see https://github.com/kazuho/ieee754.js/blob/master/ieee754.js | ||
* @param {!Uint8Array|!Array<number>} buffer The buffer. | ||
* @param {number} index The index to read from the buffer. | ||
* @param {number} ebits The number of bits of the exponent. | ||
* @param {number} fbits The number of bits of the fraction. | ||
* @return {number} The floating point number. | ||
*/ | ||
function unpack(buffer, index, ebits, fbits) {} | ||
export class IEEE754Buffer { | ||
/** | ||
* Pack a IEEE 754 floating point number. | ||
* @param {number} ebits The exponent bits. | ||
* @param {number} fbits The fraction bits. | ||
*/ | ||
constructor(ebits, fbits) {} | ||
/** | ||
* Pack a IEEE 754 floating point number. | ||
* @param {!Uint8Array|!Array<number>} buffer The buffer. | ||
* @param {number} index The index to write on the buffer. | ||
* @param {number} num The number. | ||
* @return {number} The next index to write on the buffer. | ||
*/ | ||
pack(buffer, index, num) {} | ||
/** | ||
* Unpack a IEEE 754 floating point number. | ||
* Derived from IEEE754 by DeNA Co., Ltd., MIT License. | ||
* Adapted to handle NaN. Should port the solution to the original repo. | ||
* @param {!Uint8Array|!Array<number>} buffer The buffer. | ||
* @param {number} index The index to read from the buffer. | ||
* @return {number} The floating point number. | ||
*/ | ||
unpack(buffer, index) {} | ||
} | ||
``` | ||
@@ -114,0 +112,0 @@ |
463
26919
7
145