From e505a1215c5e1243c8790bf7d23c96c27900fff7 Mon Sep 17 00:00:00 2001 From: Brian White Date: Sun, 15 May 2011 21:25:11 -0400 Subject: Add reading/writing of floats and doubles from/to buffers Code for readIEEE754/writeIEEE754 is from jspack: http://code.google.com/p/jspack/ --- LICENSE | 3 + doc/api/buffers.markdown | 80 +++++++++++++++++++++++++++ lib/buffer.js | 95 ++++++++++++++++++++++++++++++++ lib/buffer_ieee754.js | 118 ++++++++++++++++++++++++++++++++++++++++ test/simple/test-readdouble.js | 106 ++++++++++++++++++++++++++++++++++++ test/simple/test-readfloat.js | 68 +++++++++++++++++++++++ test/simple/test-writedouble.js | 105 +++++++++++++++++++++++++++++++++++ test/simple/test-writefloat.js | 65 ++++++++++++++++++++++ 8 files changed, 640 insertions(+) create mode 100644 lib/buffer_ieee754.js create mode 100644 test/simple/test-readdouble.js create mode 100644 test/simple/test-readfloat.js create mode 100644 test/simple/test-writedouble.js create mode 100644 test/simple/test-writefloat.js diff --git a/LICENSE b/LICENSE index 3d1e95ccf6..0a4aa24162 100644 --- a/LICENSE +++ b/LICENSE @@ -66,3 +66,6 @@ The externally maintained libraries used by Node are: - tools/cpplint.py is copyright Google Inc. and released under a BSD license. + + - lib/buffer_ieee754.js is copyright 2008 Fair Oaks Labs, Inc. and released + under the New BSD license. diff --git a/doc/api/buffers.markdown b/doc/api/buffers.markdown index d3f88b79c2..616ccf6fb2 100644 --- a/doc/api/buffers.markdown +++ b/doc/api/buffers.markdown @@ -275,6 +275,48 @@ bytes from the buffer in. Works as `buffer.readUInt32`, except buffer contents are treated as twos complement signed values. +### buffer.readFloat(offset, endian) + +Reads a 32 bit float from the buffer at the specified offset. Endian must be +either 'big' or 'little' and specifies what endian ordering to read the bytes +from the buffer in. + +Example: + + var buf = new Buffer(4); + + buf[0] = 0x00; + buf[1] = 0x00; + buf[2] = 0x80; + buf[3] = 0x3f; + + console.log(buf.readFloat(0, 'little'); + + // 0x01 + +### buffer.readDouble(offset, endian) + +Reads a 64 bit double from the buffer at the specified offset. Endian must be +either 'big' or 'little' and specifies what endian ordering to read the bytes +from the buffer in. + +Example: + + var buf = new Buffer(8); + + buf[0] = 0x55; + buf[1] = 0x55; + buf[2] = 0x55; + buf[3] = 0x55; + buf[4] = 0x55; + buf[5] = 0x55; + buf[6] = 0xd5; + buf[7] = 0x3f; + + console.log(buf.readDouble(0, 'little'); + + // 0.3333333333333333 + ### buffer.writeUInt8(value, offset, endian) Writes `value` to the buffer at the specified offset with specified endian @@ -364,6 +406,44 @@ format. Note, `value` must be a valid 16 bit signed integer. Works as `buffer.writeUInt832, except value is written out as a two's complement signed integer into `buffer`. +### buffer.writeFloat(value, offset, endian) + +Writes `value` to the buffer at the specified offset with specified endian +format. Note, `value` must be a valid 32 bit float. + +Example: + + var buf = new Buffer(4); + buf.writeFloat(0xcafebabe, 0, 'big'); + + console.log(buf); + + buf.writeFloat(0xcafebabe, 0, 'little'); + + console.log(buf); + + // + // + +### buffer.writeDouble(value, offset, endian) + +Writes `value` to the buffer at the specified offset with specified endian +format. Note, `value` must be a valid 64 bit double. + +Example: + + var buf = new Buffer(8); + buf.writeFloat(0xdeadbeefcafebabe, 0, 'big'); + + console.log(buf); + + buf.writeFloat(0xdeadbeefcafebabe, 0, 'little'); + + console.log(buf); + + // + // + ### buffer.fill(value, offset=0, length=-1) diff --git a/lib/buffer.js b/lib/buffer.js index 5df6f915f1..b47dd715a8 100644 --- a/lib/buffer.js +++ b/lib/buffer.js @@ -20,6 +20,7 @@ // USE OR OTHER DEALINGS IN THE SOFTWARE. var SlowBuffer = process.binding('buffer').SlowBuffer; +var IEEE754 = require('buffer_ieee754'); var assert = require('assert'); @@ -684,6 +685,43 @@ Buffer.prototype.readInt32 = function(offset, endian) { }; +Buffer.prototype.readFloat = function(offset, endian) { + var buffer = this; + + assert.ok(endian !== undefined && endian !== null, + 'missing endian'); + + assert.ok(endian == 'big' || endian == 'little', + 'bad endian value'); + + assert.ok(offset !== undefined && offset !== null, + 'missing offset'); + + assert.ok(offset + 3 < buffer.length, + 'Trying to read beyond buffer length'); + + return IEEE754.readIEEE754(buffer, offset, endian, 23, 4); +}; + +Buffer.prototype.readDouble = function(offset, endian) { + var buffer = this; + + assert.ok(endian !== undefined && endian !== null, + 'missing endian'); + + assert.ok(endian == 'big' || endian == 'little', + 'bad endian value'); + + assert.ok(offset !== undefined && offset !== null, + 'missing offset'); + + assert.ok(offset + 7 < buffer.length, + 'Trying to read beyond buffer length'); + + return IEEE754.readIEEE754(buffer, offset, endian, 52, 8); +}; + + /* * We have to make sure that the value is a valid integer. This means that it is * non-negative. It has no fractional component and that it does not exceed the @@ -843,6 +881,17 @@ function verifsint(value, max, min) { assert.ok(Math.floor(value) === value, 'value has a fractional component'); } + +function verifIEEE754(value, max, min) { + assert.ok(typeof (value) == 'number', + 'cannot write a non-number as a number'); + + assert.ok(value <= max, 'value larger than maximum allowed value'); + + assert.ok(value >= min, 'value smaller than minimum allowed value'); +} + + Buffer.prototype.writeInt8 = function(value, offset, endian) { var buffer = this; @@ -924,3 +973,49 @@ Buffer.prototype.writeInt32 = function(value, offset, endian) { buffer.writeUInt32(0xffffffff + value + 1, offset, endian); } }; + + +Buffer.prototype.writeFloat = function(value, offset, endian) { + var buffer = this; + + assert.ok(value !== undefined && value !== null, + 'missing value'); + + assert.ok(endian !== undefined && endian !== null, + 'missing endian'); + + assert.ok(endian == 'big' || endian == 'little', + 'bad endian value'); + + assert.ok(offset !== undefined && offset !== null, + 'missing offset'); + + assert.ok(offset + 3 < buffer.length, + 'Trying to read beyond buffer length'); + + verifIEEE754(value, 3.4028234663852886e+38, -3.4028234663852886e+38); + IEEE754.writeIEEE754(buffer, value, offset, endian, 23, 4); +}; + + +Buffer.prototype.writeDouble = function(value, offset, endian) { + var buffer = this; + + assert.ok(value !== undefined && value !== null, + 'missing value'); + + assert.ok(endian !== undefined && endian !== null, + 'missing endian'); + + assert.ok(endian == 'big' || endian == 'little', + 'bad endian value'); + + assert.ok(offset !== undefined && offset !== null, + 'missing offset'); + + assert.ok(offset + 7 < buffer.length, + 'Trying to read beyond buffer length'); + + verifIEEE754(value, 1.7976931348623157E+308, -1.7976931348623157E+308); + IEEE754.writeIEEE754(buffer, value, offset, endian, 52, 8); +}; diff --git a/lib/buffer_ieee754.js b/lib/buffer_ieee754.js new file mode 100644 index 0000000000..5d2af613b9 --- /dev/null +++ b/lib/buffer_ieee754.js @@ -0,0 +1,118 @@ +// Copyright (c) 2008, Fair Oaks Labs, Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * Neither the name of Fair Oaks Labs, Inc. nor the names of its contributors +// may be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// +// Modifications to writeIEEE754 to support negative zeroes made by Brian White + +exports.readIEEE754 = function(buffer, offset, endian, mLen, nBytes) { + var e, m, + bBE = (endian === 'big'), + eLen = nBytes * 8 - mLen - 1, + eMax = (1 << eLen) - 1, + eBias = eMax >> 1, + nBits = -7, + i = bBE ? 0 : (nBytes - 1), + d = bBE ? 1 : -1, + s = buffer[offset + i]; + + i += d; + + e = s & ((1 << (-nBits)) - 1); + s >>= (-nBits); + nBits += eLen; + for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8); + + m = e & ((1 << (-nBits)) - 1); + e >>= (-nBits); + nBits += mLen; + for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8); + + if (e === 0) { + e = 1 - eBias; + } else if (e === eMax) { + return m ? NaN : ((s ? -1 : 1) * Infinity); + } else { + m = m + Math.pow(2, mLen); + e = e - eBias; + } + return (s ? -1 : 1) * m * Math.pow(2, e - mLen); +}; + +exports.writeIEEE754 = function(buffer, value, offset, endian, mLen, nBytes) { + var e, m, c, + bBE = (endian === 'big'), + eLen = nBytes * 8 - mLen - 1, + eMax = (1 << eLen) - 1, + eBias = eMax >> 1, + rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0), + i = bBE ? (nBytes-1) : 0, + d = bBE ? -1 : 1, + s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0; + + value = Math.abs(value); + + if (isNaN(value) || value === Infinity) { + m = isNaN(value) ? 1 : 0; + e = eMax; + } else { + e = Math.floor(Math.log(value) / Math.LN2); + if (value * (c = Math.pow(2, -e)) < 1) { + e--; + c *= 2; + } + if (e+eBias >= 1) { + value += rt / c; + } else { + value += rt * Math.pow(2, 1 - eBias); + } + if (value * c >= 2) { + e++; + c /= 2; + } + + if (e + eBias >= eMax) { + m = 0; + e = eMax; + } else if (e + eBias >= 1) { + m = (value * c - 1) * Math.pow(2, mLen); + e = e + eBias; + } else { + m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen); + e = 0; + } + } + + for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8); + + e = (e << mLen) | m; + eLen += mLen; + for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8); + + buffer[offset + i - d] |= s * 128; +}; diff --git a/test/simple/test-readdouble.js b/test/simple/test-readdouble.js new file mode 100644 index 0000000000..0a41547bf2 --- /dev/null +++ b/test/simple/test-readdouble.js @@ -0,0 +1,106 @@ +/* + * Tests to verify we're reading in doubles correctly + */ +var ASSERT = require('assert'); + +/* + * Test (64 bit) double + */ +function test() { + var buffer = new Buffer(8); + buffer[0] = 0x55; + buffer[1] = 0x55; + buffer[2] = 0x55; + buffer[3] = 0x55; + buffer[4] = 0x55; + buffer[5] = 0x55; + buffer[6] = 0xd5; + buffer[7] = 0x3f; + ASSERT.equal(1.1945305291680097e+103, buffer.readDouble(0, 'big')); + ASSERT.equal(0.3333333333333333, buffer.readDouble(0, 'little')); + + buffer[0] = 1; + buffer[1] = 0; + buffer[2] = 0; + buffer[3] = 0; + buffer[4] = 0; + buffer[5] = 0; + buffer[6] = 0xf0; + buffer[7] = 0x3f; + ASSERT.equal(7.291122019655968e-304, buffer.readDouble(0, 'big')); + ASSERT.equal(1.0000000000000002, buffer.readDouble(0, 'little')); + + buffer[0] = 2; + ASSERT.equal(4.778309726801735e-299, buffer.readDouble(0, 'big')); + ASSERT.equal(1.0000000000000004, buffer.readDouble(0, 'little')); + + buffer[0] = 1; + buffer[6] = 0; + buffer[7] = 0; + ASSERT.equal(7.291122019556398e-304, buffer.readDouble(0, 'big')); + ASSERT.equal(5e-324, buffer.readDouble(0, 'little')); + + buffer[0] = 0xff; + buffer[1] = 0xff; + buffer[2] = 0xff; + buffer[3] = 0xff; + buffer[4] = 0xff; + buffer[5] = 0xff; + buffer[6] = 0x0f; + buffer[7] = 0x00; + ASSERT.ok(isNaN(buffer.readDouble(0, 'big'))); + ASSERT.equal(2.225073858507201e-308, buffer.readDouble(0, 'little')); + + buffer[6] = 0xef; + buffer[7] = 0x7f; + ASSERT.ok(isNaN(buffer.readDouble(0, 'big'))); + ASSERT.equal(1.7976931348623157e+308, buffer.readDouble(0, 'little')); + + buffer[0] = 0; + buffer[1] = 0; + buffer[2] = 0; + buffer[3] = 0; + buffer[4] = 0; + buffer[5] = 0; + buffer[6] = 0xf0; + buffer[7] = 0x3f; + ASSERT.equal(3.03865e-319, buffer.readDouble(0, 'big')); + ASSERT.equal(1, buffer.readDouble(0, 'little')); + + buffer[6] = 0; + buffer[7] = 0x40; + ASSERT.equal(3.16e-322, buffer.readDouble(0, 'big')); + ASSERT.equal(2, buffer.readDouble(0, 'little')); + + buffer[7] = 0xc0; + ASSERT.equal(9.5e-322, buffer.readDouble(0, 'big')); + ASSERT.equal(-2, buffer.readDouble(0, 'little')); + + buffer[6] = 0x10; + buffer[7] = 0; + ASSERT.equal(2.0237e-320, buffer.readDouble(0, 'big')); + ASSERT.equal(2.2250738585072014e-308, buffer.readDouble(0, 'little')); + + buffer[6] = 0; + ASSERT.equal(0, buffer.readDouble(0, 'big')); + ASSERT.equal(0, buffer.readDouble(0, 'little')); + ASSERT.equal(false, 1/buffer.readDouble(0, 'little')<0); + + buffer[7] = 0x80; + ASSERT.equal(6.3e-322, buffer.readDouble(0, 'big')); + ASSERT.equal(0, buffer.readDouble(0, 'little')); + ASSERT.equal(true, 1/buffer.readDouble(0, 'little')<0); + + buffer[6] = 0xf0; + buffer[7] = 0x7f; + ASSERT.equal(3.0418e-319, buffer.readDouble(0, 'big')); + ASSERT.equal(Infinity, buffer.readDouble(0, 'little')); + + buffer[6] = 0xf0; + buffer[7] = 0xff; + ASSERT.equal(3.04814e-319, buffer.readDouble(0, 'big')); + ASSERT.equal(-Infinity, buffer.readDouble(0, 'little')); +} + + +test(); diff --git a/test/simple/test-readfloat.js b/test/simple/test-readfloat.js new file mode 100644 index 0000000000..7127239e05 --- /dev/null +++ b/test/simple/test-readfloat.js @@ -0,0 +1,68 @@ +/* + * Tests to verify we're reading in floats correctly + */ +var ASSERT = require('assert'); + +/* + * Test (32 bit) float + */ +function test() { + var buffer = new Buffer(4); + buffer[0] = 0; + buffer[1] = 0; + buffer[2] = 0x80; + buffer[3] = 0x3f; + ASSERT.equal(4.600602988224807e-41, buffer.readFloat(0, 'big')); + ASSERT.equal(1, buffer.readFloat(0, 'little')); + + buffer[0] = 0; + buffer[1] = 0; + buffer[2] = 0; + buffer[3] = 0xc0; + ASSERT.equal(2.6904930515036488e-43, buffer.readFloat(0, 'big')); + ASSERT.equal(-2, buffer.readFloat(0, 'little')); + + buffer[0] = 0xff; + buffer[1] = 0xff; + buffer[2] = 0x7f; + buffer[3] = 0x7f; + ASSERT.ok(isNaN(buffer.readFloat(0, 'big'))); + ASSERT.equal(3.4028234663852886e+38, buffer.readFloat(0, 'little')); + + buffer[0] = 0xab; + buffer[1] = 0xaa; + buffer[2] = 0xaa; + buffer[3] = 0x3e; + ASSERT.equal(-1.2126478207002966e-12, buffer.readFloat(0, 'big')); + ASSERT.equal(0.3333333432674408, buffer.readFloat(0, 'little')); + + buffer[0] = 0; + buffer[1] = 0; + buffer[2] = 0; + buffer[3] = 0; + ASSERT.equal(0, buffer.readFloat(0, 'big')); + ASSERT.equal(0, buffer.readFloat(0, 'little')); + ASSERT.equal(false, 1/buffer.readFloat(0, 'little')<0); + + buffer[3] = 0x80; + ASSERT.equal(1.793662034335766e-43, buffer.readFloat(0, 'big')); + ASSERT.equal(0, buffer.readFloat(0, 'little')); + ASSERT.equal(true, 1/buffer.readFloat(0, 'little')<0); + + buffer[0] = 0; + buffer[1] = 0; + buffer[2] = 0x80; + buffer[3] = 0x7f; + ASSERT.equal(4.609571298396486e-41, buffer.readFloat(0, 'big')); + ASSERT.equal(Infinity, buffer.readFloat(0, 'little')); + + buffer[0] = 0; + buffer[1] = 0; + buffer[2] = 0x80; + buffer[3] = 0xff; + ASSERT.equal(4.627507918739843e-41, buffer.readFloat(0, 'big')); + ASSERT.equal(-Infinity, buffer.readFloat(0, 'little')); +} + + +test(); diff --git a/test/simple/test-writedouble.js b/test/simple/test-writedouble.js new file mode 100644 index 0000000000..a1bc438b48 --- /dev/null +++ b/test/simple/test-writedouble.js @@ -0,0 +1,105 @@ +/* + * Tests to verify we're writing doubles correctly + */ +var ASSERT = require('assert'); + +function test() { + var buffer = new Buffer(16); + buffer.writeDouble(2.225073858507201e-308, 0, 'big'); + buffer.writeDouble(2.225073858507201e-308, 8, 'little'); + ASSERT.equal(0x00, buffer[0]); + ASSERT.equal(0x0f, buffer[1]); + ASSERT.equal(0xff, buffer[2]); + ASSERT.equal(0xff, buffer[3]); + ASSERT.equal(0xff, buffer[4]); + ASSERT.equal(0xff, buffer[5]); + ASSERT.equal(0xff, buffer[6]); + ASSERT.equal(0xff, buffer[7]); + ASSERT.equal(0xff, buffer[8]); + ASSERT.equal(0xff, buffer[9]); + ASSERT.equal(0xff, buffer[10]); + ASSERT.equal(0xff, buffer[11]); + ASSERT.equal(0xff, buffer[12]); + ASSERT.equal(0xff, buffer[13]); + ASSERT.equal(0x0f, buffer[14]); + ASSERT.equal(0x00, buffer[15]); + + buffer.writeDouble(1.0000000000000004, 0, 'big'); + buffer.writeDouble(1.0000000000000004, 8, 'little'); + ASSERT.equal(0x3f, buffer[0]); + ASSERT.equal(0xf0, buffer[1]); + ASSERT.equal(0x00, buffer[2]); + ASSERT.equal(0x00, buffer[3]); + ASSERT.equal(0x00, buffer[4]); + ASSERT.equal(0x00, buffer[5]); + ASSERT.equal(0x00, buffer[6]); + ASSERT.equal(0x02, buffer[7]); + ASSERT.equal(0x02, buffer[8]); + ASSERT.equal(0x00, buffer[9]); + ASSERT.equal(0x00, buffer[10]); + ASSERT.equal(0x00, buffer[11]); + ASSERT.equal(0x00, buffer[12]); + ASSERT.equal(0x00, buffer[13]); + ASSERT.equal(0xf0, buffer[14]); + ASSERT.equal(0x3f, buffer[15]); + + buffer.writeDouble(-2, 0, 'big'); + buffer.writeDouble(-2, 8, 'little'); + ASSERT.equal(0xc0, buffer[0]); + ASSERT.equal(0x00, buffer[1]); + ASSERT.equal(0x00, buffer[2]); + ASSERT.equal(0x00, buffer[3]); + ASSERT.equal(0x00, buffer[4]); + ASSERT.equal(0x00, buffer[5]); + ASSERT.equal(0x00, buffer[6]); + ASSERT.equal(0x00, buffer[7]); + ASSERT.equal(0x00, buffer[8]); + ASSERT.equal(0x00, buffer[9]); + ASSERT.equal(0x00, buffer[10]); + ASSERT.equal(0x00, buffer[11]); + ASSERT.equal(0x00, buffer[12]); + ASSERT.equal(0x00, buffer[13]); + ASSERT.equal(0x00, buffer[14]); + ASSERT.equal(0xc0, buffer[15]); + + buffer.writeDouble(1.7976931348623157e+308, 0, 'big'); + buffer.writeDouble(1.7976931348623157e+308, 8, 'little'); + ASSERT.equal(0x7f, buffer[0]); + ASSERT.equal(0xef, buffer[1]); + ASSERT.equal(0xff, buffer[2]); + ASSERT.equal(0xff, buffer[3]); + ASSERT.equal(0xff, buffer[4]); + ASSERT.equal(0xff, buffer[5]); + ASSERT.equal(0xff, buffer[6]); + ASSERT.equal(0xff, buffer[7]); + ASSERT.equal(0xff, buffer[8]); + ASSERT.equal(0xff, buffer[9]); + ASSERT.equal(0xff, buffer[10]); + ASSERT.equal(0xff, buffer[11]); + ASSERT.equal(0xff, buffer[12]); + ASSERT.equal(0xff, buffer[13]); + ASSERT.equal(0xef, buffer[14]); + ASSERT.equal(0x7f, buffer[15]); + + buffer.writeDouble(0*-1, 0, 'big'); + buffer.writeDouble(0*-1, 8, 'little'); + ASSERT.equal(0x80, buffer[0]); + ASSERT.equal(0x00, buffer[1]); + ASSERT.equal(0x00, buffer[2]); + ASSERT.equal(0x00, buffer[3]); + ASSERT.equal(0x00, buffer[4]); + ASSERT.equal(0x00, buffer[5]); + ASSERT.equal(0x00, buffer[6]); + ASSERT.equal(0x00, buffer[7]); + ASSERT.equal(0x00, buffer[8]); + ASSERT.equal(0x00, buffer[9]); + ASSERT.equal(0x00, buffer[10]); + ASSERT.equal(0x00, buffer[11]); + ASSERT.equal(0x00, buffer[12]); + ASSERT.equal(0x00, buffer[13]); + ASSERT.equal(0x00, buffer[14]); + ASSERT.equal(0x80, buffer[15]); +} + + +test(); diff --git a/test/simple/test-writefloat.js b/test/simple/test-writefloat.js new file mode 100644 index 0000000000..85d3d6279d --- /dev/null +++ b/test/simple/test-writefloat.js @@ -0,0 +1,65 @@ +/* + * Tests to verify we're writing floats correctly + */ +var ASSERT = require('assert'); + +function test() { + var buffer = new Buffer(8); + buffer.writeFloat(1, 0, 'big'); + buffer.writeFloat(1, 4, 'little'); + ASSERT.equal(0x3f, buffer[0]); + ASSERT.equal(0x80, buffer[1]); + ASSERT.equal(0x00, buffer[2]); + ASSERT.equal(0x00, buffer[3]); + ASSERT.equal(0x00, buffer[4]); + ASSERT.equal(0x00, buffer[5]); + ASSERT.equal(0x80, buffer[6]); + ASSERT.equal(0x3f, buffer[7]); + + buffer.writeFloat(1.793662034335766e-43, 0, 'big'); + buffer.writeFloat(1.793662034335766e-43, 4, 'little'); + ASSERT.equal(0x00, buffer[0]); + ASSERT.equal(0x00, buffer[1]); + ASSERT.equal(0x00, buffer[2]); + ASSERT.equal(0x80, buffer[3]); + ASSERT.equal(0x80, buffer[4]); + ASSERT.equal(0x00, buffer[5]); + ASSERT.equal(0x00, buffer[6]); + ASSERT.equal(0x00, buffer[7]); + + buffer.writeFloat(1/3, 0, 'big'); + buffer.writeFloat(1/3, 4, 'little'); + ASSERT.equal(0x3e, buffer[0]); + ASSERT.equal(0xaa, buffer[1]); + ASSERT.equal(0xaa, buffer[2]); + ASSERT.equal(0xab, buffer[3]); + ASSERT.equal(0xab, buffer[4]); + ASSERT.equal(0xaa, buffer[5]); + ASSERT.equal(0xaa, buffer[6]); + ASSERT.equal(0x3e, buffer[7]); + + buffer.writeFloat(3.4028234663852886e+38, 0, 'big'); + buffer.writeFloat(3.4028234663852886e+38, 4, 'little'); + ASSERT.equal(0x7f, buffer[0]); + ASSERT.equal(0x7f, buffer[1]); + ASSERT.equal(0xff, buffer[2]); + ASSERT.equal(0xff, buffer[3]); + ASSERT.equal(0xff, buffer[4]); + ASSERT.equal(0xff, buffer[5]); + ASSERT.equal(0x7f, buffer[6]); + ASSERT.equal(0x7f, buffer[7]); + + buffer.writeFloat(0*-1, 0, 'big'); + buffer.writeFloat(0*-1, 4, 'little'); + ASSERT.equal(0x80, buffer[0]); + ASSERT.equal(0x00, buffer[1]); + ASSERT.equal(0x00, buffer[2]); + ASSERT.equal(0x00, buffer[3]); + ASSERT.equal(0x00, buffer[4]); + ASSERT.equal(0x00, buffer[5]); + ASSERT.equal(0x00, buffer[6]); + ASSERT.equal(0x80, buffer[7]); +} + + +test(); -- cgit v1.2.3