# float16

IEEE 754 half-precision floating-point for JavaScript
See the archive of the ES Discuss Float16Array topic for details

npm downloads jsDelivr hits npm version deno version
dependencies license codecov

Sauce Labs browser matrix

## Install ### Node.js ```console npm install @petamoriken/float16 ``` ```console yarn add @petamoriken/float16 ``` ### Bun ```console bun add @petamoriken/float16 ``` ## Import ### Node.js, Bun or Bundler (webpack, rollup.js, esbuild, etc) ```js // ES Modules import { Float16Array, isFloat16Array, isTypedArray, getFloat16, setFloat16, f16round, } from "@petamoriken/float16"; ``` ```js // CommonJS const { Float16Array, isFloat16Array, isTypedArray, getFloat16, setFloat16, f16round, } = require("@petamoriken/float16"); ``` ### Deno You can get modules from the [deno.land/x](https://deno.land/x/float16) hosting service. ```ts import { Float16Array, isFloat16Array, isTypedArray, getFloat16, setFloat16, f16round, } from "https://deno.land/x/float16/mod.ts"; ``` ### Browser Deliver a `browser/float16.mjs` or `browser/float16.js` file in the npm package from your Web server with the JavaScript `Content-Type` HTTP header. ```html ``` ```html ```
Or, you can use jsDelivr CDN. ```html ``` ```html ```
## Support engines **This package only requires ES2015 features** and does not use environment-dependent features (except for `inspect/`), so you can use it without any problems. It works fine with [the current officially supported versions of Node.js](https://github.com/nodejs/Release). `Float16Array` implemented by `Proxy` and `Reflect`, so IE11 is never supported even if you use polyfills. ### Pre-transpiled JavaScript files (CommonJS, IIFE) `lib/` and `browser/` directories in the npm package have JavaScript files already transpiled, and they have been tested automatically in the following environments: - Node.js: Active LTS - Firefox: last 2 versions and ESR - Chrome: last 2 versions - Edge: last 2 versions - Safari: last 2 versions ## API ### `Float16Array` `Float16Array` is similar to `TypedArray` such as `Float32Array` ([MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Float32Array)). ```js const array = new Float16Array([1.0, 1.1, 1.2, 1.3]); for (const value of array) { // 1, 1.099609375, 1.2001953125, 1.2998046875 console.log(value); } // Float16Array(4) [ 2, 2.19921875, 2.3984375, 2.599609375 ] array.map((value) => value * 2); ``` ### `isFloat16Array` `isFloat16Array` is a utility function to check whether the value given as an argument is an instance of `Float16Array` or not. ```js const buffer = new ArrayBuffer(256); // true isFloat16Array(new Float16Array(buffer)); // false isFloat16Array(new Float32Array(buffer)); isFloat16Array(new Uint16Array(buffer)); isFloat16Array(new DataView(buffer)); ``` ### `isTypedArray` `isTypedArray` is a utility function to check whether the value given as an argument is an instance of a type of `TypedArray` or not. Unlike `util.types.isTypedArray` in Node.js, this returns `true` for `Float16Array`. ```js const buffer = new ArrayBuffer(256); // true isTypedArray(new Float16Array(buffer)); isTypedArray(new Float32Array(buffer)); isTypedArray(new Uint16Array(buffer)); // false isTypedArray(new DataView(buffer)); ``` ### `getFloat16`, `setFloat16` `getFloat16` and `setFloat16` are similar to `DataView` methods such as `DataView#getFloat32` ([MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView/getFloat32)) and `DataView#setFloat32` ([MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView/setFloat32)). ```ts declare function getFloat16(view: DataView, byteOffset: number, littleEndian?: boolean): number; declare function setFloat16(view: DataView, byteOffset: number, value: number, littleEndian?: boolean): void; ``` ```js const buffer = new ArrayBuffer(256); const view = new DataView(buffer); view.setUint16(0, 0x1234); getFloat16(view, 0); // 0.0007572174072265625 // You can append methods to DataView instance view.getFloat16 = (...args) => getFloat16(view, ...args); view.setFloat16 = (...args) => setFloat16(view, ...args); view.getFloat16(0); // 0.0007572174072265625 view.setFloat16(0, Math.PI, true); view.getFloat16(0, true); // 3.140625 ``` ### `f16round` (alias: `hfround`) `f16round` is similar to `Math.fround` ([MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/fround)). This function returns nearest half-precision float representation of a number. ```ts declare function f16round(x: number): number; ``` ```js Math.fround(1.337); // 1.3370000123977661 f16round(1.337); // 1.3369140625 ``` ## `Float16Array` limitations (edge cases)
Float16Array has some limitations, because it is impossible to completely reproduce the behavior of TypedArray. Be careful when checking if it is a TypedArray or not by using ArrayBuffer.isView, and when using Web standards such as structuredClone and WebGL. ### Built-in functions Built-in `TypedArray` objects use "internal slots" for built-in methods. Some limitations exist because the `Proxy` object can't trap internal slots ([explanation](https://javascript.info/proxy#built-in-objects-internal-slots)). This package isn't polyfill, in other words, it doesn't change native global functions and static/prototype methods. E.g. `ArrayBuffer.isView` is the butlt-in method that checks if it has the `[[ViewedArrayBuffer]]` internal slot. It returns `false` for `Proxy` object such as `Float16Array` instance. ```js ArrayBuffer.isView(new Float32Array(10)); // true ArrayBuffer.isView(new Float16Array(10)); // false ``` ### The structured clone algorithm (Web Workers, IndexedDB, etc) The structured clone algorithm copies complex JavaScript objects. It is used internally when invoking `structuredClone()`, to transfer data between Web Workers via `postMessage()`, storing objects with IndexedDB, or copying objects for other APIs ([MDN](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm)). It can't clone `Proxy` object such as `Float16Array` instance, you need to convert it to `Uint16Array` or deal with `ArrayBuffer` directly. ```js const array = new Float16Array([1.0, 1.1, 1.2]); const cloned = structuredClone({ buffer: array.buffer }); ``` ### WebGL WebGL requires `Uint16Array` for buffer or texture data whose types are `gl.HALF_FLOAT` (WebGL 2) or `ext.HALF_FLOAT_OES` (WebGL 1 extension). Do not apply the `Float16Array` object directly to `gl.bufferData` or `gl.texImage2D` etc. ```js // WebGL 2 example const vertices = new Float16Array([ -0.5, -0.5, 0, 0.5, -0.5, 0, 0.5, 0.5, 0, ]); const buffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, buffer); // wrap in Uint16Array gl.bufferData(gl.ARRAY_BUFFER, new Uint16Array(vertices.buffer), gl.STATIC_DRAW); gl.vertexAttribPointer(location, 3, gl.HALF_FLOAT, false, 0, 0); gl.bindBuffer(gl.ARRAY_BUFFER, null); gl.enableVertexAttribArray(location); ``` ### Others See JSDoc comments in `src/Float16Array.mjs` for details. If you don't write hacky code, you shouldn't have any problems.
## `Float16Array` custom inspection
Provides custom inspection for Node.js and Deno, which makes the results of console.log more readable. ### Node.js ```js // ES Modules import { Float16Array } from "@petamoriken/float16"; import { customInspect } from "@petamoriken/float16/inspect"; Float16Array.prototype[Symbol.for("nodejs.util.inspect.custom")] = customInspect; ``` ```js // CommonJS const { Float16Array } = require("@petamoriken/float16"); const { customInspect } = require("@petamoriken/float16/inspect"); Float16Array.prototype[Symbol.for("nodejs.util.inspect.custom")] = customInspect; ``` ### Deno ```ts import { Float16Array } from "https://deno.land/x/float16/mod.ts"; import { customInspect } from "https://deno.land/x/float16/inspect.ts"; // deno-lint-ignore no-explicit-any (Float16Array.prototype as any)[Symbol.for("Deno.customInspect")] = customInspect; ```
## Development
Manual build and test ### Manual build This repository uses corepack for package manager manager. You may have to activate yarn in corepack. ```console corepack enable yarn ``` Download devDependencies. ```console yarn ``` Build `lib/`, `browser/` files. ```console yarn run build ``` Build `docs/` files (for browser test). ```console yarn run docs ``` ### Test This repository uses corepack for package manager manager. You may have to activate yarn in corepack. ```console corepack enable yarn ``` Download devDependencies. ```console yarn ``` #### Node.js test ```console NODE_ENV=test yarn build:lib yarn test ``` #### Browser test ```console NODE_ENV=test yarn build:browser yarn docs ``` Access `docs/test/index.html` with browsers. You can access current [test page](https://petamoriken.github.io/float16/test) ([power-assert version](https://petamoriken.github.io/float16/test/power)) in `master` branch.
## License MIT License This software contains productions that are distributed under [the Apache 2.0 License](http://www.apache.org/licenses/LICENSE-2.0). Specifically, `index.d.ts` is modified from the original [TypeScript lib files](https://github.com/microsoft/TypeScript/tree/main/src/lib).