Full Code of evanw/float-toy for AI

gh-pages 1ea0d374417b cached
3 files
59.1 KB
16.2k tokens
83 symbols
1 requests
Download .txt
Repository: evanw/float-toy
Branch: gh-pages
Commit: 1ea0d374417b
Files: 3
Total size: 59.1 KB

Directory structure:
gitextract_qxpuqoni/

├── README.md
├── float16.js
└── index.html

================================================
FILE CONTENTS
================================================

================================================
FILE: README.md
================================================
# Float Toy

Visit [http://evanw.github.io/float-toy/](http://evanw.github.io/float-toy/) to play around.
Use this to build intuition for the IEEE floating-point format.


================================================
FILE: float16.js
================================================
/**
 * @petamoriken/float16 aa4af43 | MIT License - https://git.io/float16
 *
 * @license
 * lodash-es v4.17.15 | MIT License - https://lodash.com/custom-builds
 */

var float16 = (function (exports) {
    'use strict';

    // algorithm: ftp://ftp.fox-toolkit.org/pub/fasthalffloatconversion.pdf
    const buffer = new ArrayBuffer(4);
    const floatView = new Float32Array(buffer);
    const uint32View = new Uint32Array(buffer);
    const baseTable = new Uint32Array(512);
    const shiftTable = new Uint32Array(512);

    for (let i = 0; i < 256; ++i) {
      const e = i - 127; // very small number (0, -0)

      if (e < -27) {
        baseTable[i | 0x000] = 0x0000;
        baseTable[i | 0x100] = 0x8000;
        shiftTable[i | 0x000] = 24;
        shiftTable[i | 0x100] = 24; // small number (denorm)
      } else if (e < -14) {
        baseTable[i | 0x000] = 0x0400 >> -e - 14;
        baseTable[i | 0x100] = 0x0400 >> -e - 14 | 0x8000;
        shiftTable[i | 0x000] = -e - 1;
        shiftTable[i | 0x100] = -e - 1; // normal number
      } else if (e <= 15) {
        baseTable[i | 0x000] = e + 15 << 10;
        baseTable[i | 0x100] = e + 15 << 10 | 0x8000;
        shiftTable[i | 0x000] = 13;
        shiftTable[i | 0x100] = 13; // large number (Infinity, -Infinity)
      } else if (e < 128) {
        baseTable[i | 0x000] = 0x7c00;
        baseTable[i | 0x100] = 0xfc00;
        shiftTable[i | 0x000] = 24;
        shiftTable[i | 0x100] = 24; // stay (NaN, Infinity, -Infinity)
      } else {
        baseTable[i | 0x000] = 0x7c00;
        baseTable[i | 0x100] = 0xfc00;
        shiftTable[i | 0x000] = 13;
        shiftTable[i | 0x100] = 13;
      }
    }
    /**
     * round a number to a half float number bits.
     * @param {number} num
     */


    function roundToFloat16Bits(num) {
      floatView[0] = num;
      const f = uint32View[0];
      const e = f >> 23 & 0x1ff;
      return baseTable[e] + ((f & 0x007fffff) >> shiftTable[e]);
    }
    const mantissaTable = new Uint32Array(2048);
    const exponentTable = new Uint32Array(64);
    const offsetTable = new Uint32Array(64);
    mantissaTable[0] = 0;

    for (let i = 1; i < 1024; ++i) {
      let m = i << 13; // zero pad mantissa bits

      let e = 0; // zero exponent
      // normalized

      while ((m & 0x00800000) === 0) {
        e -= 0x00800000; // decrement exponent

        m <<= 1;
      }

      m &= ~0x00800000; // clear leading 1 bit

      e += 0x38800000; // adjust bias

      mantissaTable[i] = m | e;
    }

    for (let i = 1024; i < 2048; ++i) {
      mantissaTable[i] = 0x38000000 + (i - 1024 << 13);
    }

    exponentTable[0] = 0;

    for (let i = 1; i < 31; ++i) {
      exponentTable[i] = i << 23;
    }

    exponentTable[31] = 0x47800000;
    exponentTable[32] = 0x80000000;

    for (let i = 33; i < 63; ++i) {
      exponentTable[i] = 0x80000000 + (i - 32 << 23);
    }

    exponentTable[63] = 0xc7800000;
    offsetTable[0] = 0;

    for (let i = 1; i < 64; ++i) {
      if (i === 32) {
        offsetTable[i] = 0;
      } else {
        offsetTable[i] = 1024;
      }
    }
    /**
     * convert a half float number bits to a number.
     * @param {number} float16bits - half float number bits
     */


    function convertToNumber(float16bits) {
      const m = float16bits >> 10;
      uint32View[0] = mantissaTable[offsetTable[m] + (float16bits & 0x3ff)] + exponentTable[m];
      return floatView[0];
    }

    /**
     * returns the nearest half precision float representation of a number.
     * @param {number} num
     */

    function hfround(num) {
      num = Number(num); // for optimization

      if (!Number.isFinite(num) || num === 0) {
        return num;
      }

      const x16 = roundToFloat16Bits(num);
      return convertToNumber(x16);
    }

    function ToInteger(num) {
      if (typeof num !== "number") num = Number(num);
      if (Number.isNaN(num)) num = 0;
      return Math.trunc(num);
    }
    function defaultCompareFunction(x, y) {
      const [isNaN_x, isNaN_y] = [Number.isNaN(x), Number.isNaN(y)];
      if (isNaN_x && isNaN_y) return 0;
      if (isNaN_x) return 1;
      if (isNaN_y) return -1;
      if (x < y) return -1;
      if (x > y) return 1;

      if (x === 0 && y === 0) {
        const [isPlusZero_x, isPlusZero_y] = [Object.is(x, 0), Object.is(y, 0)];
        if (!isPlusZero_x && isPlusZero_y) return -1;
        if (isPlusZero_x && !isPlusZero_y) return 1;
      }

      return 0;
    }

    /** Detect free variable `global` from Node.js. */
    var freeGlobal = typeof global == 'object' && global && global.Object === Object && global;

    /** Detect free variable `self`. */

    var freeSelf = typeof self == 'object' && self && self.Object === Object && self;
    /** Used as a reference to the global object. */

    var root = freeGlobal || freeSelf || Function('return this')();

    /** Built-in value references. */

    var Symbol$1 = root.Symbol;

    /** Used for built-in method references. */

    var objectProto = Object.prototype;
    /** Used to check objects for own properties. */

    var hasOwnProperty = objectProto.hasOwnProperty;
    /**
     * Used to resolve the
     * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
     * of values.
     */

    var nativeObjectToString = objectProto.toString;
    /** Built-in value references. */

    var symToStringTag = Symbol$1 ? Symbol$1.toStringTag : undefined;
    /**
     * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.
     *
     * @private
     * @param {*} value The value to query.
     * @returns {string} Returns the raw `toStringTag`.
     */

    function getRawTag(value) {
      var isOwn = hasOwnProperty.call(value, symToStringTag),
          tag = value[symToStringTag];

      try {
        value[symToStringTag] = undefined;
        var unmasked = true;
      } catch (e) {}

      var result = nativeObjectToString.call(value);

      if (unmasked) {
        if (isOwn) {
          value[symToStringTag] = tag;
        } else {
          delete value[symToStringTag];
        }
      }

      return result;
    }

    /** Used for built-in method references. */
    var objectProto$1 = Object.prototype;
    /**
     * Used to resolve the
     * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
     * of values.
     */

    var nativeObjectToString$1 = objectProto$1.toString;
    /**
     * Converts `value` to a string using `Object.prototype.toString`.
     *
     * @private
     * @param {*} value The value to convert.
     * @returns {string} Returns the converted string.
     */

    function objectToString(value) {
      return nativeObjectToString$1.call(value);
    }

    /** `Object#toString` result references. */

    var nullTag = '[object Null]',
        undefinedTag = '[object Undefined]';
    /** Built-in value references. */

    var symToStringTag$1 = Symbol$1 ? Symbol$1.toStringTag : undefined;
    /**
     * The base implementation of `getTag` without fallbacks for buggy environments.
     *
     * @private
     * @param {*} value The value to query.
     * @returns {string} Returns the `toStringTag`.
     */

    function baseGetTag(value) {
      if (value == null) {
        return value === undefined ? undefinedTag : nullTag;
      }

      return symToStringTag$1 && symToStringTag$1 in Object(value) ? getRawTag(value) : objectToString(value);
    }

    /**
     * Checks if `value` is object-like. A value is object-like if it's not `null`
     * and has a `typeof` result of "object".
     *
     * @static
     * @memberOf _
     * @since 4.0.0
     * @category Lang
     * @param {*} value The value to check.
     * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
     * @example
     *
     * _.isObjectLike({});
     * // => true
     *
     * _.isObjectLike([1, 2, 3]);
     * // => true
     *
     * _.isObjectLike(_.noop);
     * // => false
     *
     * _.isObjectLike(null);
     * // => false
     */
    function isObjectLike(value) {
      return value != null && typeof value == 'object';
    }

    var arrayBufferTag = '[object ArrayBuffer]';
    /**
     * The base implementation of `_.isArrayBuffer` without Node.js optimizations.
     *
     * @private
     * @param {*} value The value to check.
     * @returns {boolean} Returns `true` if `value` is an array buffer, else `false`.
     */

    function baseIsArrayBuffer(value) {
      return isObjectLike(value) && baseGetTag(value) == arrayBufferTag;
    }

    /**
     * The base implementation of `_.unary` without support for storing metadata.
     *
     * @private
     * @param {Function} func The function to cap arguments for.
     * @returns {Function} Returns the new capped function.
     */
    function baseUnary(func) {
      return function (value) {
        return func(value);
      };
    }

    /** Detect free variable `exports`. */

    var freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports;
    /** Detect free variable `module`. */

    var freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module;
    /** Detect the popular CommonJS extension `module.exports`. */

    var moduleExports = freeModule && freeModule.exports === freeExports;
    /** Detect free variable `process` from Node.js. */

    var freeProcess = moduleExports && freeGlobal.process;
    /** Used to access faster Node.js helpers. */

    var nodeUtil = function () {
      try {
        // Use `util.types` for Node.js 10+.
        var types = freeModule && freeModule.require && freeModule.require('util').types;

        if (types) {
          return types;
        } // Legacy `process.binding('util')` for Node.js < 10.


        return freeProcess && freeProcess.binding && freeProcess.binding('util');
      } catch (e) {}
    }();

    /* Node.js helper references. */

    var nodeIsArrayBuffer = nodeUtil && nodeUtil.isArrayBuffer;
    /**
     * Checks if `value` is classified as an `ArrayBuffer` object.
     *
     * @static
     * @memberOf _
     * @since 4.3.0
     * @category Lang
     * @param {*} value The value to check.
     * @returns {boolean} Returns `true` if `value` is an array buffer, else `false`.
     * @example
     *
     * _.isArrayBuffer(new ArrayBuffer(2));
     * // => true
     *
     * _.isArrayBuffer(new Array(2));
     * // => false
     */

    var isArrayBuffer = nodeIsArrayBuffer ? baseUnary(nodeIsArrayBuffer) : baseIsArrayBuffer;

    function isDataView(view) {
      return view instanceof DataView;
    }
    function isStringNumberKey(key) {
      return typeof key === "string" && key === ToInteger(key) + "";
    }

    function createPrivateStorage() {
      const wm = new WeakMap();
      return self => {
        let obj = wm.get(self);

        if (obj) {
          return obj;
        } else {
          obj = Object.create(null);
          wm.set(self, obj);
          return obj;
        }
      };
    }

    /**
     * Checks if `value` is the
     * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
     * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
     *
     * @static
     * @memberOf _
     * @since 0.1.0
     * @category Lang
     * @param {*} value The value to check.
     * @returns {boolean} Returns `true` if `value` is an object, else `false`.
     * @example
     *
     * _.isObject({});
     * // => true
     *
     * _.isObject([1, 2, 3]);
     * // => true
     *
     * _.isObject(_.noop);
     * // => true
     *
     * _.isObject(null);
     * // => false
     */
    function isObject(value) {
      var type = typeof value;
      return value != null && (type == 'object' || type == 'function');
    }

    /** `Object#toString` result references. */

    var asyncTag = '[object AsyncFunction]',
        funcTag = '[object Function]',
        genTag = '[object GeneratorFunction]',
        proxyTag = '[object Proxy]';
    /**
     * Checks if `value` is classified as a `Function` object.
     *
     * @static
     * @memberOf _
     * @since 0.1.0
     * @category Lang
     * @param {*} value The value to check.
     * @returns {boolean} Returns `true` if `value` is a function, else `false`.
     * @example
     *
     * _.isFunction(_);
     * // => true
     *
     * _.isFunction(/abc/);
     * // => false
     */

    function isFunction(value) {
      if (!isObject(value)) {
        return false;
      } // The use of `Object#toString` avoids issues with the `typeof` operator
      // in Safari 9 which returns 'object' for typed arrays and other constructors.


      var tag = baseGetTag(value);
      return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag;
    }

    /** Used to detect overreaching core-js shims. */

    var coreJsData = root['__core-js_shared__'];

    /** Used to detect methods masquerading as native. */

    var maskSrcKey = function () {
      var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || '');
      return uid ? 'Symbol(src)_1.' + uid : '';
    }();
    /**
     * Checks if `func` has its source masked.
     *
     * @private
     * @param {Function} func The function to check.
     * @returns {boolean} Returns `true` if `func` is masked, else `false`.
     */


    function isMasked(func) {
      return !!maskSrcKey && maskSrcKey in func;
    }

    /** Used for built-in method references. */
    var funcProto = Function.prototype;
    /** Used to resolve the decompiled source of functions. */

    var funcToString = funcProto.toString;
    /**
     * Converts `func` to its source code.
     *
     * @private
     * @param {Function} func The function to convert.
     * @returns {string} Returns the source code.
     */

    function toSource(func) {
      if (func != null) {
        try {
          return funcToString.call(func);
        } catch (e) {}

        try {
          return func + '';
        } catch (e) {}
      }

      return '';
    }

    /**
     * Used to match `RegExp`
     * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).
     */

    var reRegExpChar = /[\\^$.*+?()[\]{}|]/g;
    /** Used to detect host constructors (Safari). */

    var reIsHostCtor = /^\[object .+?Constructor\]$/;
    /** Used for built-in method references. */

    var funcProto$1 = Function.prototype,
        objectProto$2 = Object.prototype;
    /** Used to resolve the decompiled source of functions. */

    var funcToString$1 = funcProto$1.toString;
    /** Used to check objects for own properties. */

    var hasOwnProperty$1 = objectProto$2.hasOwnProperty;
    /** Used to detect if a method is native. */

    var reIsNative = RegExp('^' + funcToString$1.call(hasOwnProperty$1).replace(reRegExpChar, '\\$&').replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$');
    /**
     * The base implementation of `_.isNative` without bad shim checks.
     *
     * @private
     * @param {*} value The value to check.
     * @returns {boolean} Returns `true` if `value` is a native function,
     *  else `false`.
     */

    function baseIsNative(value) {
      if (!isObject(value) || isMasked(value)) {
        return false;
      }

      var pattern = isFunction(value) ? reIsNative : reIsHostCtor;
      return pattern.test(toSource(value));
    }

    /**
     * Gets the value at `key` of `object`.
     *
     * @private
     * @param {Object} [object] The object to query.
     * @param {string} key The key of the property to get.
     * @returns {*} Returns the property value.
     */
    function getValue(object, key) {
      return object == null ? undefined : object[key];
    }

    /**
     * Gets the native function at `key` of `object`.
     *
     * @private
     * @param {Object} object The object to query.
     * @param {string} key The key of the method to get.
     * @returns {*} Returns the function if it's native, else `undefined`.
     */

    function getNative(object, key) {
      var value = getValue(object, key);
      return baseIsNative(value) ? value : undefined;
    }

    /* Built-in method references that are verified to be native. */

    var nativeCreate = getNative(Object, 'create');

    /**
     * Removes all key-value entries from the hash.
     *
     * @private
     * @name clear
     * @memberOf Hash
     */

    function hashClear() {
      this.__data__ = nativeCreate ? nativeCreate(null) : {};
      this.size = 0;
    }

    /**
     * Removes `key` and its value from the hash.
     *
     * @private
     * @name delete
     * @memberOf Hash
     * @param {Object} hash The hash to modify.
     * @param {string} key The key of the value to remove.
     * @returns {boolean} Returns `true` if the entry was removed, else `false`.
     */
    function hashDelete(key) {
      var result = this.has(key) && delete this.__data__[key];
      this.size -= result ? 1 : 0;
      return result;
    }

    /** Used to stand-in for `undefined` hash values. */

    var HASH_UNDEFINED = '__lodash_hash_undefined__';
    /** Used for built-in method references. */

    var objectProto$3 = Object.prototype;
    /** Used to check objects for own properties. */

    var hasOwnProperty$2 = objectProto$3.hasOwnProperty;
    /**
     * Gets the hash value for `key`.
     *
     * @private
     * @name get
     * @memberOf Hash
     * @param {string} key The key of the value to get.
     * @returns {*} Returns the entry value.
     */

    function hashGet(key) {
      var data = this.__data__;

      if (nativeCreate) {
        var result = data[key];
        return result === HASH_UNDEFINED ? undefined : result;
      }

      return hasOwnProperty$2.call(data, key) ? data[key] : undefined;
    }

    /** Used for built-in method references. */

    var objectProto$4 = Object.prototype;
    /** Used to check objects for own properties. */

    var hasOwnProperty$3 = objectProto$4.hasOwnProperty;
    /**
     * Checks if a hash value for `key` exists.
     *
     * @private
     * @name has
     * @memberOf Hash
     * @param {string} key The key of the entry to check.
     * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
     */

    function hashHas(key) {
      var data = this.__data__;
      return nativeCreate ? data[key] !== undefined : hasOwnProperty$3.call(data, key);
    }

    /** Used to stand-in for `undefined` hash values. */

    var HASH_UNDEFINED$1 = '__lodash_hash_undefined__';
    /**
     * Sets the hash `key` to `value`.
     *
     * @private
     * @name set
     * @memberOf Hash
     * @param {string} key The key of the value to set.
     * @param {*} value The value to set.
     * @returns {Object} Returns the hash instance.
     */

    function hashSet(key, value) {
      var data = this.__data__;
      this.size += this.has(key) ? 0 : 1;
      data[key] = nativeCreate && value === undefined ? HASH_UNDEFINED$1 : value;
      return this;
    }

    /**
     * Creates a hash object.
     *
     * @private
     * @constructor
     * @param {Array} [entries] The key-value pairs to cache.
     */

    function Hash(entries) {
      var index = -1,
          length = entries == null ? 0 : entries.length;
      this.clear();

      while (++index < length) {
        var entry = entries[index];
        this.set(entry[0], entry[1]);
      }
    } // Add methods to `Hash`.


    Hash.prototype.clear = hashClear;
    Hash.prototype['delete'] = hashDelete;
    Hash.prototype.get = hashGet;
    Hash.prototype.has = hashHas;
    Hash.prototype.set = hashSet;

    /**
     * Removes all key-value entries from the list cache.
     *
     * @private
     * @name clear
     * @memberOf ListCache
     */
    function listCacheClear() {
      this.__data__ = [];
      this.size = 0;
    }

    /**
     * Performs a
     * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
     * comparison between two values to determine if they are equivalent.
     *
     * @static
     * @memberOf _
     * @since 4.0.0
     * @category Lang
     * @param {*} value The value to compare.
     * @param {*} other The other value to compare.
     * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
     * @example
     *
     * var object = { 'a': 1 };
     * var other = { 'a': 1 };
     *
     * _.eq(object, object);
     * // => true
     *
     * _.eq(object, other);
     * // => false
     *
     * _.eq('a', 'a');
     * // => true
     *
     * _.eq('a', Object('a'));
     * // => false
     *
     * _.eq(NaN, NaN);
     * // => true
     */
    function eq(value, other) {
      return value === other || value !== value && other !== other;
    }

    /**
     * Gets the index at which the `key` is found in `array` of key-value pairs.
     *
     * @private
     * @param {Array} array The array to inspect.
     * @param {*} key The key to search for.
     * @returns {number} Returns the index of the matched value, else `-1`.
     */

    function assocIndexOf(array, key) {
      var length = array.length;

      while (length--) {
        if (eq(array[length][0], key)) {
          return length;
        }
      }

      return -1;
    }

    /** Used for built-in method references. */

    var arrayProto = Array.prototype;
    /** Built-in value references. */

    var splice = arrayProto.splice;
    /**
     * Removes `key` and its value from the list cache.
     *
     * @private
     * @name delete
     * @memberOf ListCache
     * @param {string} key The key of the value to remove.
     * @returns {boolean} Returns `true` if the entry was removed, else `false`.
     */

    function listCacheDelete(key) {
      var data = this.__data__,
          index = assocIndexOf(data, key);

      if (index < 0) {
        return false;
      }

      var lastIndex = data.length - 1;

      if (index == lastIndex) {
        data.pop();
      } else {
        splice.call(data, index, 1);
      }

      --this.size;
      return true;
    }

    /**
     * Gets the list cache value for `key`.
     *
     * @private
     * @name get
     * @memberOf ListCache
     * @param {string} key The key of the value to get.
     * @returns {*} Returns the entry value.
     */

    function listCacheGet(key) {
      var data = this.__data__,
          index = assocIndexOf(data, key);
      return index < 0 ? undefined : data[index][1];
    }

    /**
     * Checks if a list cache value for `key` exists.
     *
     * @private
     * @name has
     * @memberOf ListCache
     * @param {string} key The key of the entry to check.
     * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
     */

    function listCacheHas(key) {
      return assocIndexOf(this.__data__, key) > -1;
    }

    /**
     * Sets the list cache `key` to `value`.
     *
     * @private
     * @name set
     * @memberOf ListCache
     * @param {string} key The key of the value to set.
     * @param {*} value The value to set.
     * @returns {Object} Returns the list cache instance.
     */

    function listCacheSet(key, value) {
      var data = this.__data__,
          index = assocIndexOf(data, key);

      if (index < 0) {
        ++this.size;
        data.push([key, value]);
      } else {
        data[index][1] = value;
      }

      return this;
    }

    /**
     * Creates an list cache object.
     *
     * @private
     * @constructor
     * @param {Array} [entries] The key-value pairs to cache.
     */

    function ListCache(entries) {
      var index = -1,
          length = entries == null ? 0 : entries.length;
      this.clear();

      while (++index < length) {
        var entry = entries[index];
        this.set(entry[0], entry[1]);
      }
    } // Add methods to `ListCache`.


    ListCache.prototype.clear = listCacheClear;
    ListCache.prototype['delete'] = listCacheDelete;
    ListCache.prototype.get = listCacheGet;
    ListCache.prototype.has = listCacheHas;
    ListCache.prototype.set = listCacheSet;

    /* Built-in method references that are verified to be native. */

    var Map = getNative(root, 'Map');

    /**
     * Removes all key-value entries from the map.
     *
     * @private
     * @name clear
     * @memberOf MapCache
     */

    function mapCacheClear() {
      this.size = 0;
      this.__data__ = {
        'hash': new Hash(),
        'map': new (Map || ListCache)(),
        'string': new Hash()
      };
    }

    /**
     * Checks if `value` is suitable for use as unique object key.
     *
     * @private
     * @param {*} value The value to check.
     * @returns {boolean} Returns `true` if `value` is suitable, else `false`.
     */
    function isKeyable(value) {
      var type = typeof value;
      return type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean' ? value !== '__proto__' : value === null;
    }

    /**
     * Gets the data for `map`.
     *
     * @private
     * @param {Object} map The map to query.
     * @param {string} key The reference key.
     * @returns {*} Returns the map data.
     */

    function getMapData(map, key) {
      var data = map.__data__;
      return isKeyable(key) ? data[typeof key == 'string' ? 'string' : 'hash'] : data.map;
    }

    /**
     * Removes `key` and its value from the map.
     *
     * @private
     * @name delete
     * @memberOf MapCache
     * @param {string} key The key of the value to remove.
     * @returns {boolean} Returns `true` if the entry was removed, else `false`.
     */

    function mapCacheDelete(key) {
      var result = getMapData(this, key)['delete'](key);
      this.size -= result ? 1 : 0;
      return result;
    }

    /**
     * Gets the map value for `key`.
     *
     * @private
     * @name get
     * @memberOf MapCache
     * @param {string} key The key of the value to get.
     * @returns {*} Returns the entry value.
     */

    function mapCacheGet(key) {
      return getMapData(this, key).get(key);
    }

    /**
     * Checks if a map value for `key` exists.
     *
     * @private
     * @name has
     * @memberOf MapCache
     * @param {string} key The key of the entry to check.
     * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
     */

    function mapCacheHas(key) {
      return getMapData(this, key).has(key);
    }

    /**
     * Sets the map `key` to `value`.
     *
     * @private
     * @name set
     * @memberOf MapCache
     * @param {string} key The key of the value to set.
     * @param {*} value The value to set.
     * @returns {Object} Returns the map cache instance.
     */

    function mapCacheSet(key, value) {
      var data = getMapData(this, key),
          size = data.size;
      data.set(key, value);
      this.size += data.size == size ? 0 : 1;
      return this;
    }

    /**
     * Creates a map cache object to store key-value pairs.
     *
     * @private
     * @constructor
     * @param {Array} [entries] The key-value pairs to cache.
     */

    function MapCache(entries) {
      var index = -1,
          length = entries == null ? 0 : entries.length;
      this.clear();

      while (++index < length) {
        var entry = entries[index];
        this.set(entry[0], entry[1]);
      }
    } // Add methods to `MapCache`.


    MapCache.prototype.clear = mapCacheClear;
    MapCache.prototype['delete'] = mapCacheDelete;
    MapCache.prototype.get = mapCacheGet;
    MapCache.prototype.has = mapCacheHas;
    MapCache.prototype.set = mapCacheSet;

    /** Error message constants. */

    var FUNC_ERROR_TEXT = 'Expected a function';
    /**
     * Creates a function that memoizes the result of `func`. If `resolver` is
     * provided, it determines the cache key for storing the result based on the
     * arguments provided to the memoized function. By default, the first argument
     * provided to the memoized function is used as the map cache key. The `func`
     * is invoked with the `this` binding of the memoized function.
     *
     * **Note:** The cache is exposed as the `cache` property on the memoized
     * function. Its creation may be customized by replacing the `_.memoize.Cache`
     * constructor with one whose instances implement the
     * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object)
     * method interface of `clear`, `delete`, `get`, `has`, and `set`.
     *
     * @static
     * @memberOf _
     * @since 0.1.0
     * @category Function
     * @param {Function} func The function to have its output memoized.
     * @param {Function} [resolver] The function to resolve the cache key.
     * @returns {Function} Returns the new memoized function.
     * @example
     *
     * var object = { 'a': 1, 'b': 2 };
     * var other = { 'c': 3, 'd': 4 };
     *
     * var values = _.memoize(_.values);
     * values(object);
     * // => [1, 2]
     *
     * values(other);
     * // => [3, 4]
     *
     * object.a = 2;
     * values(object);
     * // => [1, 2]
     *
     * // Modify the result cache.
     * values.cache.set(object, ['a', 'b']);
     * values(object);
     * // => ['a', 'b']
     *
     * // Replace `_.memoize.Cache`.
     * _.memoize.Cache = WeakMap;
     */

    function memoize(func, resolver) {
      if (typeof func != 'function' || resolver != null && typeof resolver != 'function') {
        throw new TypeError(FUNC_ERROR_TEXT);
      }

      var memoized = function memoized() {
        var args = arguments,
            key = resolver ? resolver.apply(this, args) : args[0],
            cache = memoized.cache;

        if (cache.has(key)) {
          return cache.get(key);
        }

        var result = func.apply(this, args);
        memoized.cache = cache.set(key, result) || cache;
        return result;
      };

      memoized.cache = new (memoize.Cache || MapCache)();
      return memoized;
    } // Expose `MapCache`.


    memoize.Cache = MapCache;

    // JavaScriptCore bug: https://bugs.webkit.org/show_bug.cgi?id=171606
    const isTypedArrayIndexedPropertyWritable = Object.getOwnPropertyDescriptor(new Uint8Array(1), 0).writable;

    const _ = createPrivateStorage();

    function isFloat16Array(target) {
      return target instanceof Float16Array;
    }

    function assertFloat16Array(target) {
      if (!isFloat16Array(target)) {
        throw new TypeError("This is not a Float16Array");
      }
    }

    function isDefaultFloat16ArrayMethods(target) {
      return typeof target === "function" && defaultFloat16ArrayMethods.has(target);
    }

    function copyToArray(float16bits) {
      const length = float16bits.length;
      const array = new Array(length);

      for (let i = 0; i < length; ++i) {
        array[i] = convertToNumber(float16bits[i]);
      }

      return array;
    } // proxy handler


    const applyHandler = {
      apply(func, thisArg, args) {
        // peel off proxy
        if (isFloat16Array(thisArg) && isDefaultFloat16ArrayMethods(func)) return Reflect.apply(func, _(thisArg).target, args);
        return Reflect.apply(func, thisArg, args);
      }

    };
    const handler = {
      get(target, key) {
        let wrapper = null;

        if (!isTypedArrayIndexedPropertyWritable) {
          wrapper = target;
          target = _(wrapper).target;
        }

        if (isStringNumberKey(key)) {
          return Reflect.has(target, key) ? convertToNumber(Reflect.get(target, key)) : undefined;
        } else {
          const ret = wrapper !== null && Reflect.has(wrapper, key) ? Reflect.get(wrapper, key) : Reflect.get(target, key);
          if (typeof ret !== "function") return ret; // TypedArray methods can't be called by Proxy Object

          let proxy = _(ret).proxy;

          if (proxy === undefined) {
            proxy = _(ret).proxy = new Proxy(ret, applyHandler);
          }

          return proxy;
        }
      },

      set(target, key, value) {
        let wrapper = null;

        if (!isTypedArrayIndexedPropertyWritable) {
          wrapper = target;
          target = _(wrapper).target;
        }

        if (isStringNumberKey(key)) {
          return Reflect.set(target, key, roundToFloat16Bits(value));
        } else {
          // frozen object can't change prototype property
          if (wrapper !== null && (!Reflect.has(target, key) || Object.isFrozen(wrapper))) {
            return Reflect.set(wrapper, key, value);
          } else {
            return Reflect.set(target, key, value);
          }
        }
      }

    };

    if (!isTypedArrayIndexedPropertyWritable) {
      handler.getPrototypeOf = wrapper => Reflect.getPrototypeOf(_(wrapper).target);

      handler.setPrototypeOf = (wrapper, prototype) => Reflect.setPrototypeOf(_(wrapper).target, prototype);

      handler.defineProperty = (wrapper, key, descriptor) => {
        const target = _(wrapper).target;

        return !Reflect.has(target, key) || Object.isFrozen(wrapper) ? Reflect.defineProperty(wrapper, key, descriptor) : Reflect.defineProperty(target, key, descriptor);
      };

      handler.deleteProperty = (wrapper, key) => {
        const target = _(wrapper).target;

        return Reflect.has(wrapper, key) ? Reflect.deleteProperty(wrapper, key) : Reflect.deleteProperty(target, key);
      };

      handler.has = (wrapper, key) => Reflect.has(wrapper, key) || Reflect.has(_(wrapper).target, key);

      handler.isExtensible = wrapper => Reflect.isExtensible(wrapper);

      handler.preventExtensions = wrapper => Reflect.preventExtensions(wrapper);

      handler.getOwnPropertyDescriptor = (wrapper, key) => Reflect.getOwnPropertyDescriptor(wrapper, key);

      handler.ownKeys = wrapper => Reflect.ownKeys(wrapper);
    }

    class Float16Array extends Uint16Array {
      constructor(input, byteOffset, length) {
        // input Float16Array
        if (isFloat16Array(input)) {
          super(_(input).target); // 22.2.1.3, 22.2.1.4 TypedArray, Array, ArrayLike, Iterable
        } else if (input !== null && typeof input === "object" && !isArrayBuffer(input)) {
          // if input is not ArrayLike and Iterable, get Array
          const arrayLike = !Reflect.has(input, "length") && input[Symbol.iterator] !== undefined ? [...input] : input;
          const length = arrayLike.length;
          super(length);

          for (let i = 0; i < length; ++i) {
            // super (Uint16Array)
            this[i] = roundToFloat16Bits(arrayLike[i]);
          } // 22.2.1.2, 22.2.1.5 primitive, ArrayBuffer

        } else {
          switch (arguments.length) {
            case 0:
              super();
              break;

            case 1:
              super(input);
              break;

            case 2:
              super(input, byteOffset);
              break;

            case 3:
              super(input, byteOffset, length);
              break;

            default:
              super(...arguments);
          }
        }

        let proxy;

        if (isTypedArrayIndexedPropertyWritable) {
          proxy = new Proxy(this, handler);
        } else {
          const wrapper = Object.create(null);
          _(wrapper).target = this;
          proxy = new Proxy(wrapper, handler);
        } // proxy private storage


        _(proxy).target = this; // this private storage

        _(this).proxy = proxy;
        return proxy;
      } // static methods


      static from(src) {
        if ((arguments.length <= 1 ? 0 : arguments.length - 1) === 0) return new Float16Array(Uint16Array.from(src, roundToFloat16Bits).buffer);
        const mapFunc = arguments.length <= 1 ? undefined : arguments[1];
        const thisArg = arguments.length <= 2 ? undefined : arguments[2];
        return new Float16Array(Uint16Array.from(src, function (val) {
          for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
            args[_key - 1] = arguments[_key];
          }

          return roundToFloat16Bits(mapFunc.call(this, val, ...args));
        }, thisArg).buffer);
      }

      static of() {
        for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
          args[_key2] = arguments[_key2];
        }

        return new Float16Array(args);
      } // iterate methods


      *[Symbol.iterator]() {
        for (const val of super[Symbol.iterator]()) {
          yield convertToNumber(val);
        }
      }

      keys() {
        return super.keys();
      }

      *values() {
        for (const val of super.values()) {
          yield convertToNumber(val);
        }
      }

      *entries() {
        for (const [i, val] of super.entries()) {
          yield [i, convertToNumber(val)];
        }
      } // functional methods


      map(callback) {
        assertFloat16Array(this);
        const thisArg = arguments.length <= 1 ? undefined : arguments[1];
        const array = [];

        for (let i = 0, l = this.length; i < l; ++i) {
          const val = convertToNumber(this[i]);
          array.push(callback.call(thisArg, val, i, _(this).proxy));
        }

        return new Float16Array(array);
      }

      filter(callback) {
        assertFloat16Array(this);
        const thisArg = arguments.length <= 1 ? undefined : arguments[1];
        const array = [];

        for (let i = 0, l = this.length; i < l; ++i) {
          const val = convertToNumber(this[i]);

          if (callback.call(thisArg, val, i, _(this).proxy)) {
            array.push(val);
          }
        }

        return new Float16Array(array);
      }

      reduce(callback) {
        assertFloat16Array(this);
        let val, start;

        if ((arguments.length <= 1 ? 0 : arguments.length - 1) === 0) {
          val = convertToNumber(this[0]);
          start = 1;
        } else {
          val = arguments.length <= 1 ? undefined : arguments[1];
          start = 0;
        }

        for (let i = start, l = this.length; i < l; ++i) {
          val = callback(val, convertToNumber(this[i]), i, _(this).proxy);
        }

        return val;
      }

      reduceRight(callback) {
        assertFloat16Array(this);
        let val, start;
        const length = this.length;

        if ((arguments.length <= 1 ? 0 : arguments.length - 1) === 0) {
          val = convertToNumber(this[length - 1]);
          start = length - 1;
        } else {
          val = arguments.length <= 1 ? undefined : arguments[1];
          start = length;
        }

        for (let i = start; i--;) {
          val = callback(val, convertToNumber(this[i]), i, _(this).proxy);
        }

        return val;
      }

      forEach(callback) {
        assertFloat16Array(this);
        const thisArg = arguments.length <= 1 ? undefined : arguments[1];

        for (let i = 0, l = this.length; i < l; ++i) {
          callback.call(thisArg, convertToNumber(this[i]), i, _(this).proxy);
        }
      }

      find(callback) {
        assertFloat16Array(this);
        const thisArg = arguments.length <= 1 ? undefined : arguments[1];

        for (let i = 0, l = this.length; i < l; ++i) {
          const value = convertToNumber(this[i]);
          if (callback.call(thisArg, value, i, _(this).proxy)) return value;
        }
      }

      findIndex(callback) {
        assertFloat16Array(this);
        const thisArg = arguments.length <= 1 ? undefined : arguments[1];

        for (let i = 0, l = this.length; i < l; ++i) {
          const value = convertToNumber(this[i]);
          if (callback.call(thisArg, value, i, _(this).proxy)) return i;
        }

        return -1;
      }

      every(callback) {
        assertFloat16Array(this);
        const thisArg = arguments.length <= 1 ? undefined : arguments[1];

        for (let i = 0, l = this.length; i < l; ++i) {
          if (!callback.call(thisArg, convertToNumber(this[i]), i, _(this).proxy)) return false;
        }

        return true;
      }

      some(callback) {
        assertFloat16Array(this);
        const thisArg = arguments.length <= 1 ? undefined : arguments[1];

        for (let i = 0, l = this.length; i < l; ++i) {
          if (callback.call(thisArg, convertToNumber(this[i]), i, _(this).proxy)) return true;
        }

        return false;
      } // change element methods


      set(input) {
        assertFloat16Array(this);
        const offset = arguments.length <= 1 ? undefined : arguments[1];
        let float16bits; // input Float16Array

        if (isFloat16Array(input)) {
          float16bits = _(input).target; // input others
        } else {
          const arrayLike = !Reflect.has(input, "length") && input[Symbol.iterator] !== undefined ? [...input] : input;
          const length = arrayLike.length;
          float16bits = new Uint16Array(length);

          for (let i = 0, l = arrayLike.length; i < l; ++i) {
            float16bits[i] = roundToFloat16Bits(arrayLike[i]);
          }
        }

        super.set(float16bits, offset);
      }

      reverse() {
        assertFloat16Array(this);
        super.reverse();
        return _(this).proxy;
      }

      fill(value) {
        assertFloat16Array(this);

        for (var _len3 = arguments.length, opts = new Array(_len3 > 1 ? _len3 - 1 : 0), _key3 = 1; _key3 < _len3; _key3++) {
          opts[_key3 - 1] = arguments[_key3];
        }

        super.fill(roundToFloat16Bits(value), ...opts);
        return _(this).proxy;
      }

      copyWithin(target, start) {
        assertFloat16Array(this);

        for (var _len4 = arguments.length, opts = new Array(_len4 > 2 ? _len4 - 2 : 0), _key4 = 2; _key4 < _len4; _key4++) {
          opts[_key4 - 2] = arguments[_key4];
        }

        super.copyWithin(target, start, ...opts);
        return _(this).proxy;
      }

      sort() {
        assertFloat16Array(this);
        let compareFunction = arguments.length <= 0 ? undefined : arguments[0];

        if (compareFunction === undefined) {
          compareFunction = defaultCompareFunction;
        }

        const _convertToNumber = memoize(convertToNumber);

        super.sort((x, y) => compareFunction(_convertToNumber(x), _convertToNumber(y)));
        return _(this).proxy;
      } // copy element methods


      slice() {
        assertFloat16Array(this);
        let float16bits; // V8, SpiderMonkey, JavaScriptCore, Chakra throw TypeError

        try {
          float16bits = super.slice(...arguments);
        } catch (e) {
          if (e instanceof TypeError) {
            const uint16 = new Uint16Array(this.buffer, this.byteOffset, this.length);
            float16bits = uint16.slice(...arguments);
          } else {
            throw e;
          }
        }

        return new Float16Array(float16bits.buffer);
      }

      subarray() {
        assertFloat16Array(this);
        let float16bits; // V8, SpiderMonkey, JavaScriptCore, Chakra throw TypeError

        try {
          float16bits = super.subarray(...arguments);
        } catch (e) {
          if (e instanceof TypeError) {
            const uint16 = new Uint16Array(this.buffer, this.byteOffset, this.length);
            float16bits = uint16.subarray(...arguments);
          } else {
            throw e;
          }
        }

        return new Float16Array(float16bits.buffer, float16bits.byteOffset, float16bits.length);
      } // contains methods


      indexOf(element) {
        assertFloat16Array(this);
        const length = this.length;
        let from = ToInteger(arguments.length <= 1 ? undefined : arguments[1]);

        if (from < 0) {
          from += length;
          if (from < 0) from = 0;
        }

        for (let i = from, l = length; i < l; ++i) {
          if (convertToNumber(this[i]) === element) return i;
        }

        return -1;
      }

      lastIndexOf(element) {
        assertFloat16Array(this);
        const length = this.length;
        let from = ToInteger(arguments.length <= 1 ? undefined : arguments[1]);
        from = from === 0 ? length : from + 1;

        if (from >= 0) {
          from = from < length ? from : length;
        } else {
          from += length;
        }

        for (let i = from; i--;) {
          if (convertToNumber(this[i]) === element) return i;
        }

        return -1;
      }

      includes(element) {
        assertFloat16Array(this);
        const length = this.length;
        let from = ToInteger(arguments.length <= 1 ? undefined : arguments[1]);

        if (from < 0) {
          from += length;
          if (from < 0) from = 0;
        }

        const isNaN = Number.isNaN(element);

        for (let i = from, l = length; i < l; ++i) {
          const value = convertToNumber(this[i]);
          if (isNaN && Number.isNaN(value)) return true;
          if (value === element) return true;
        }

        return false;
      } // string methods


      join() {
        assertFloat16Array(this);
        const array = copyToArray(this);
        return array.join(...arguments);
      }

      toLocaleString() {
        assertFloat16Array(this);
        const array = copyToArray(this);
        return array.toLocaleString(...arguments);
      }

      get [Symbol.toStringTag]() {
        if (isFloat16Array(this)) return "Float16Array";
      }

    }
    const Float16Array$prototype = Float16Array.prototype;
    const defaultFloat16ArrayMethods = new WeakSet();

    for (const key of Reflect.ownKeys(Float16Array$prototype)) {
      const val = Float16Array$prototype[key];
      if (typeof val === "function") defaultFloat16ArrayMethods.add(val);
    }

    /**
     * returns an unsigned 16-bit float at the specified byte offset from the start of the DataView.
     * @param {DataView} dataView
     * @param {nunmber} byteOffset
     * @param {*} opts
     */

    function getFloat16(dataView, byteOffset) {
      if (!isDataView(dataView)) throw new TypeError("First argument to getFloat16 function must be a DataView");

      for (var _len = arguments.length, opts = new Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
        opts[_key - 2] = arguments[_key];
      }

      return convertToNumber(dataView.getUint16(byteOffset, ...opts));
    }
    /**
     * stores an unsigned 16-bit float value at the specified byte offset from the start of the DataView.
     * @param {DataView} dataView
     * @param {number} byteOffset
     * @param {number} value
     * @param {*} opts
     */

    function setFloat16(dataView, byteOffset, value) {
      if (!isDataView(dataView)) throw new TypeError("First argument to setFloat16 function must be a DataView");

      for (var _len2 = arguments.length, opts = new Array(_len2 > 3 ? _len2 - 3 : 0), _key2 = 3; _key2 < _len2; _key2++) {
        opts[_key2 - 3] = arguments[_key2];
      }

      dataView.setUint16(byteOffset, roundToFloat16Bits(value), ...opts);
    }

    exports.Float16Array = Float16Array;
    exports.getFloat16 = getFloat16;
    exports.hfround = hfround;
    exports.setFloat16 = setFloat16;

    return exports;

}({}));


================================================
FILE: index.html
================================================
<meta charset="utf8">
<title>Float Toy</title>
<style>
  body {
    margin: 50px;
    font: 14px/20px sans-serif;
    cursor: default;
  }

  a {
    color: inherit;
  }

  p {
    margin: 30px 0;
  }

  h2 {
    margin: 60px 0 30px 0;
  }

  table {
    border-collapse: collapse;
    font-size: 20px;
    line-height: 14px;
    width: 100%;
  }

  td {
    font: inherit;
    padding: 0;
    text-align: center;
  }

  td.sign { background: #BBF; }
  td.exponent { background: #BFB; }
  td.fraction { background: #FBB; }

  td.sign.hover { background: #99D; }
  td.exponent.hover { background: #9D9; }
  td.fraction.hover { background: #D99; }

  .input td {
    border: 1px solid #000;
    padding: 5px 2px;
    font-size: 14px;
  }

  .zerox-col {
    vertical-align: bottom;
  }

  .zerox {
    height: 26px;
    line-height: 26px;
  }

  .output-col {
    width: 100%;
    vertical-align: bottom;
  }

  .hex-col {
    width: 100%;
  }

  .output {
    font: inherit;
    padding: 5px;
    margin: -5px;
    border: 0;
    outline: none;
    width: 100%;
    min-width: 200px;
    background: none;
    height: 26px;
    line-height: 26px;
    box-sizing: content-box;
  }

  .output:hover, .output:focus {
    background: rgba(0, 0, 0, 0.066);
  }

  .help {
    height: 50px;
    font-size: 20px;
    line-height: 60px;
    padding-left: 3px;
    white-space: nowrap;
  }

  .help sup {
    vertical-align: top;
    font-size: 12px;
    line-height: 50px;
  }

  .help span {
    padding: 3px;
    margin: -3px;
  }

  td.nibble {
    font-size: 10px;
    line-height: 6px;
    border: none;
  }

  td.dark.nibble {
    background: #DDD;
  }

  span.sign { background: #DDF; }
  span.exponent { background: #DFD; }
  span.fraction { background: #FDD; }

</style>
<body>
  <h1>Float Toy</h1>
  <p>
    Click on a cell below to toggle bit values, or edit the hex or decimal values directly.
    Use this to build intuition for the IEEE floating-point format.
    See Wikipedia for details on the <a href="https://en.wikipedia.org/wiki/Half-precision_floating-point_format">half-precision</a>, <a href="https://en.wikipedia.org/wiki/Single-precision_floating-point_format">single-precision</a> and <a href="https://en.wikipedia.org/wiki/Double-precision_floating-point_format">double-precision</a> floating-point formats.
  </p>

  <h2>16-bit (half)</h2>
  <table>
    <tr>
      <td><span id="input16" class="input"></span></td>
      <td class="zerox-col"><span class="zerox">&nbsp;&nbsp;=&nbsp;&nbsp;0x</span></td>
      <td class="output-col"><input id="hex16" class="output"></td>
    </tr>
  </table>
  <table>
    <tr>
      <td><span id="help16" class="help"></span></td>
      <td>&nbsp;&nbsp;=&nbsp;&nbsp;</td>
      <td class="hex-col"><input id="output16" class="output"></td>
    </tr>
  </table>

  <h2>32-bit (float)</h2>
  <table>
    <tr>
      <td><span id="input32" class="input"></span></td>
      <td class="zerox-col"><span class="zerox">&nbsp;&nbsp;=&nbsp;&nbsp;0x</span></td>
      <td class="output-col"><input id="hex32" class="output"></td>
    </tr>
  </table>
  <table>
    <tr>
      <td><span id="help32" class="help"></span></td>
      <td>&nbsp;&nbsp;=&nbsp;&nbsp;</td>
      <td class="hex-col"><input id="output32" class="output"></td>
    </tr>
  </table>

  <h2>64-bit (double)</h2>
  <table>
    <tr>
      <td><span id="input64" class="input"></span></td>
      <td class="zerox-col"><span class="zerox">&nbsp;&nbsp;=&nbsp;&nbsp;0x</span></td>
      <td class="output-col"><input id="hex64" class="output"></td>
    </tr>
  </table>
  <table>
    <tr>
      <td><span id="help64" class="help"></span></td>
      <td>&nbsp;&nbsp;=&nbsp;&nbsp;</td>
      <td class="hex-col"><input id="output64" class="output"></td>
    </tr>
  </table>
</body>
<script src="./float16.js"></script>
<script>
const {Float16Array} = float16;

(function () {

  function load(array, exponentBits, input, output, help, hex) {
    var bytes = new Uint8Array(array.buffer);
    var hexLength = bytes.length;

    function reduceNumber(x) {
      var copy = bytes.length === 2 ? new Float16Array(1) : bytes.length === 4 ? new Float32Array(1) : new Float64Array(1);
      copy[0] = +x;
      var value = copy[0];
      x = value === 0 && 1 / value === -Infinity ? '-0' : value + '';

      if (x === 'NaN' || x === 'Infinity' || x === '-Infinity') {
        return x;
      }

      var parts = /^([+-]?\d+)((?:\.\d+)?)((?:[eE][+-]?\d+)?)$/.exec(x);
      var whole = parts[1];
      var fraction = parts[2];
      var exponent = parts[3];

      // Remove digits one-by-one until the number changes
      while (fraction.length > 0) {
        // Try truncating
        var truncatedFraction = fraction.slice(0, -1);
        var text = whole + (truncatedFraction !== '.' ? truncatedFraction : '') + exponent;
        copy[0] = +text;
        var truncatedValue = copy[0];
        if (truncatedValue === value) {
          fraction = truncatedFraction;
          x = text;
          continue;
        }

        // Try rounding
        var roundedFraction = truncatedFraction;
        var i = roundedFraction.length - 1;
        var zero = '0'.charCodeAt(0);
        while (i > 0) {
          var c = roundedFraction.charCodeAt(i) - zero;
          roundedFraction = roundedFraction.slice(0, i) + String.fromCharCode((c + 1) % 10 + zero) + roundedFraction.slice(i + 1);
          if (c < 9) break; // Do we need to carry?
          i--;
        }
        var text = whole + (roundedFraction !== '.' ? roundedFraction : '') + exponent;
        copy[0] = +text;
        var roundedValue = copy[0];
        if (roundedValue === value) {
          fraction = roundedFraction;
          x = text;
          continue;
        }

        // Both numbers changed, keep the old value
        break;
      }

      return x;
    }

    // Populate HTML
    var html = '<table>';
    // The bit numbers
    html += '<tr>';
    for (var i = 0; i < bytes.length; i++) {
      for (var j = 0; j < 8; j++) {
        var index = (bytes.length - i) * 8 - j;
        if (j > 3) {
          html += '<td class="nibble">' + index + '</td>'
        } else {
          html += '<td class="dark nibble">' + index + '</td>'
        }
      }
    }
    html += '</tr>';
    // The bits
    html += '<tr>';
    for (var i = 0; i < bytes.length; i++) {
      for (var j = 0; j < 8; j++) {
        var index = i * 8 + j;
        var className =
          index === 0 ? 'sign' :
            index < 1 + exponentBits ? 'exponent' :
              'fraction';
        html += '<td data-index="' + index + '" class="' + className + '">0</td>';
      }
    }
    html += '</tr></table>';
    input.innerHTML = html;

    // Grab elements
    var elements = [];
    for (var i = 0; i < bytes.length * 8; i++) {
      (function (i) {
        var element = input.querySelector('[data-index="' + i + '"]');
        element.onmouseover = function () { this.classList.add('hover'); };
        element.onmouseout = function () { this.classList.remove('hover'); };
        elements.push(element);
      })(i);
    }

    // Event handlers
    function extractNumber() {
      return +(output.value.replace(/\b(?:infinity|inf)\b/gi, 'Infinity'));
    }
    output.onkeydown = function (e) {
      if (e.which === 13) {
        e.preventDefault();
        output.blur();
      }

      else if (e.which === 38) {
        e.preventDefault();
        output.value = reduceNumber(extractNumber() + 1);
        output.select();
        output.oninput();
      }

      else if (e.which === 40) {
        e.preventDefault();
        output.value = reduceNumber(extractNumber() - 1);
        output.select();
        output.oninput();
      }
    };
    output.onfocus = function () {
      output.select();
    };
    output.oninput = function () {
      array[0] = extractNumber();
      render();
    };
    output.onblur = function () {
      render();
    };

    hex.onkeydown = function (e) {
      if (e.which === 13) {
        e.preventDefault();
        hex.blur();
      }
    };
    hex.onfocus = function () {
      hex.select();
    };
    hex.oninput = function () {
      var hexAlphabet = '0123456789abcdefABCDEF';
      var validHexCharas = hex.value.split('').every(function (c) {
        return hexAlphabet.split('').lastIndexOf(c) !== -1;
      });
      if (hex.value.length > (hexLength * 2) || validHexCharas === false) {
        hex.value = hex.value.slice(0, -1);
        return;
      }

      var tmpBytes = toByteArray(hex.value);
      bytes.fill(0);
      bytes.set(tmpBytes.reverse(), hexLength - tmpBytes.length);
      render();
    };
    hex.onblur = function () {
      render();
    };

    input.onmousedown = function (e) {
      if ('index' in e.target.dataset) {
        var index = e.target.dataset.index | 0;
        var byteIndex = bytes.length - (index >> 3) - 1;
        var byteMask = 1 << (7 - (index & 7));
        var mouseDownValue = bytes[byteIndex] & byteMask ? 0 : 1;
        bytes[byteIndex] ^= byteMask;
        render();

        document.onmousemove = function (e2) {
          if ('index' in e2.target.dataset) {
            var index = e2.target.dataset.index | 0;
            var byteIndex = bytes.length - (index >> 3) - 1;
            var byteMask = 1 << (7 - (index & 7));
            bytes[byteIndex] = (bytes[byteIndex] & ~byteMask) | (byteMask * mouseDownValue);
            render();
          }
        };

        document.onmouseup = function () {
          document.onmousemove = null;
          document.onmouseup = null;
        };
      }
    };

    // Update loop
    function render() {
      for (var i = 0; i < bytes.length * 8; i++) {
        elements[i].textContent = ((bytes[bytes.length - (i >> 3) - 1] >> (7 - (i & 7))) & 1);
      }

      // Figure out exponent
      var exponent = 0;
      for (var i = 0; i < exponentBits; i++) {
        var index = 1 + i;
        var bit = (bytes[bytes.length - (index >> 3) - 1] >> (7 - (index & 7))) & 1;
        exponent += bit << (exponentBits - i - 1);
      }
      var exponentBias = (1 << (exponentBits - 1)) - 1;
      exponent -= exponentBias;

      // Figure out fraction
      var copyBytes = new Uint8Array(bytes);
      var copy = bytes.length === 2 ? new Float16Array(copyBytes.buffer) : bytes.length === 4 ? new Float32Array(copyBytes.buffer) : new Float64Array(copyBytes.buffer);
      for (var i = 0; i < exponentBits; i++) {
        var index = 1 + i;
        var byteIndex = bytes.length - (index >> 3) - 1;
        var byteMask = 1 << (7 - (index & 7));
        copyBytes[byteIndex] = (copyBytes[byteIndex] & ~byteMask) | (i === 0 ? 0 : byteMask);
      }
      var signIndex = bytes.length - 1;
      var signMask = 0x80;
      var sign = copyBytes[signIndex] & signMask;
      copyBytes[signIndex] &= ~signMask;
      var fraction = copy[0];

      // Handle denormal numbers
      if (exponent === -exponentBias) {
        exponent++;
        fraction--;
      }

      // Update views according to which input was edited
      if (document.activeElement === hex) {
        var value = array[0];
        output.value = reduceNumber(value === 0 && 1 / value === -Infinity ? '-0' : value);
      } else if (document.activeElement === output) {
        var tmpBytes = bytes.slice().reverse();
        hex.value = toHexString(tmpBytes);
      } else { // This branch is for when the individual bits get toggled
        var value = array[0];
        output.value = reduceNumber(value === 0 && 1 / value === -Infinity ? '-0' : value);
        var tmpBytes = bytes.slice().reverse();
        hex.value = toHexString(tmpBytes);
      }

      help.innerHTML =
        '<span class="sign">' + (sign ? -1 : 1) + '</span>' +
        '&nbsp;&nbsp;&times;&nbsp;&nbsp;' +
        '<span class="exponent">2<sup>' + exponent + '</sup></span>' +
        '&nbsp;&nbsp;&times;&nbsp;&nbsp;' +
        '<span class="fraction">' + reduceNumber(fraction) + '</span>';
    }

    function toHexString(byteArray) {
      return Array.from(byteArray, function (byte) {
        return ('0' + byte.toString(16).toUpperCase()).slice(-2);
      }).join('')
    }

    function toByteArray(hexString) {
      var result = [];
      if (hexString.length % 2 == 1) {
        hexString = hexString + '0';
      }
      for (var i = 0; i < hexString.length; i += 2) {
        result.push(parseInt(hexString.substr(i, 2), 16));
      }
      return result;
    }

    render();
  }

  load(new Float16Array([Math.PI]), 5, document.getElementById('input16'), document.getElementById('output16'), document.getElementById('help16'), document.getElementById('hex16'));
  load(new Float32Array([Math.PI]), 8, document.getElementById('input32'), document.getElementById('output32'), document.getElementById('help32'), document.getElementById('hex32'));
  load(new Float64Array([Math.PI]), 11, document.getElementById('input64'), document.getElementById('output64'), document.getElementById('help64'), document.getElementById('hex64'));

})();

</script>
Download .txt
gitextract_qxpuqoni/

├── README.md
├── float16.js
└── index.html
Download .txt
SYMBOL INDEX (83 symbols across 1 files)

FILE: float16.js
  function roundToFloat16Bits (line 54) | function roundToFloat16Bits(num) {
  function convertToNumber (line 117) | function convertToNumber(float16bits) {
  function hfround (line 128) | function hfround(num) {
  function ToInteger (line 139) | function ToInteger(num) {
  function defaultCompareFunction (line 144) | function defaultCompareFunction(x, y) {
  function getRawTag (line 199) | function getRawTag(value) {
  function objectToString (line 238) | function objectToString(value) {
  function baseGetTag (line 257) | function baseGetTag(value) {
  function isObjectLike (line 289) | function isObjectLike(value) {
  function baseIsArrayBuffer (line 302) | function baseIsArrayBuffer(value) {
  function baseUnary (line 313) | function baseUnary(func) {
  function isDataView (line 370) | function isDataView(view) {
  function isStringNumberKey (line 373) | function isStringNumberKey(key) {
  function createPrivateStorage (line 377) | function createPrivateStorage() {
  function isObject (line 417) | function isObject(value) {
  function isFunction (line 446) | function isFunction(value) {
  function isMasked (line 476) | function isMasked(func) {
  function toSource (line 493) | function toSource(func) {
  function baseIsNative (line 538) | function baseIsNative(value) {
  function getValue (line 555) | function getValue(object, key) {
  function getNative (line 568) | function getNative(object, key) {
  function hashClear (line 585) | function hashClear() {
  function hashDelete (line 600) | function hashDelete(key) {
  function hashGet (line 625) | function hashGet(key) {
  function hashHas (line 652) | function hashHas(key) {
  function hashSet (line 671) | function hashSet(key, value) {
  function Hash (line 686) | function Hash(entries) {
  function listCacheClear (line 711) | function listCacheClear() {
  function eq (line 748) | function eq(value, other) {
  function assocIndexOf (line 761) | function assocIndexOf(array, key) {
  function listCacheDelete (line 789) | function listCacheDelete(key) {
  function listCacheGet (line 819) | function listCacheGet(key) {
  function listCacheHas (line 835) | function listCacheHas(key) {
  function listCacheSet (line 850) | function listCacheSet(key, value) {
  function ListCache (line 872) | function ListCache(entries) {
  function mapCacheClear (line 902) | function mapCacheClear() {
  function isKeyable (line 918) | function isKeyable(value) {
  function getMapData (line 932) | function getMapData(map, key) {
  function mapCacheDelete (line 947) | function mapCacheDelete(key) {
  function mapCacheGet (line 963) | function mapCacheGet(key) {
  function mapCacheHas (line 977) | function mapCacheHas(key) {
  function mapCacheSet (line 992) | function mapCacheSet(key, value) {
  function MapCache (line 1008) | function MapCache(entries) {
  function memoize (line 1074) | function memoize(func, resolver) {
  function isFloat16Array (line 1105) | function isFloat16Array(target) {
  function assertFloat16Array (line 1109) | function assertFloat16Array(target) {
  function isDefaultFloat16ArrayMethods (line 1115) | function isDefaultFloat16ArrayMethods(target) {
  function copyToArray (line 1119) | function copyToArray(float16bits) {
  method apply (line 1132) | apply(func, thisArg, args) {
  method get (line 1140) | get(target, key) {
  method set (line 1164) | set(target, key, value) {
  class Float16Array (line 1214) | class Float16Array extends Uint16Array {
    method constructor (line 1215) | constructor(input, byteOffset, length) {
    method from (line 1271) | static from(src) {
    method of (line 1284) | static of() {
    method keys (line 1299) | keys() {
    method values (line 1303) | *values() {
    method entries (line 1309) | *entries() {
    method map (line 1316) | map(callback) {
    method filter (line 1329) | filter(callback) {
    method reduce (line 1345) | reduce(callback) {
    method reduceRight (line 1364) | reduceRight(callback) {
    method forEach (line 1384) | forEach(callback) {
    method find (line 1393) | find(callback) {
    method findIndex (line 1403) | findIndex(callback) {
    method every (line 1415) | every(callback) {
    method some (line 1426) | some(callback) {
    method set (line 1438) | set(input) {
    method reverse (line 1458) | reverse() {
    method fill (line 1464) | fill(value) {
    method copyWithin (line 1475) | copyWithin(target, start) {
    method sort (line 1486) | sort() {
    method slice (line 1501) | slice() {
    method subarray (line 1519) | subarray() {
    method indexOf (line 1538) | indexOf(element) {
    method lastIndexOf (line 1555) | lastIndexOf(element) {
    method includes (line 1574) | includes(element) {
    method join (line 1596) | join() {
    method toLocaleString (line 1602) | toLocaleString() {
  method [Symbol.iterator] (line 1293) | *[Symbol.iterator]() {
  method [Symbol.toStringTag] (line 1608) | get [Symbol.toStringTag]() {
  function getFloat16 (line 1628) | function getFloat16(dataView, byteOffset) {
  function setFloat16 (line 1645) | function setFloat16(dataView, byteOffset, value) {
Condensed preview — 3 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (63K chars).
[
  {
    "path": "README.md",
    "chars": 170,
    "preview": "# Float Toy\n\nVisit [http://evanw.github.io/float-toy/](http://evanw.github.io/float-toy/) to play around.\nUse this to bu"
  },
  {
    "path": "float16.js",
    "chars": 47295,
    "preview": "/**\n * @petamoriken/float16 aa4af43 | MIT License - https://git.io/float16\n *\n * @license\n * lodash-es v4.17.15 | MIT Li"
  },
  {
    "path": "index.html",
    "chars": 13030,
    "preview": "<meta charset=\"utf8\">\n<title>Float Toy</title>\n<style>\n  body {\n    margin: 50px;\n    font: 14px/20px sans-serif;\n    cu"
  }
]

About this extraction

This page contains the full source code of the evanw/float-toy GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 3 files (59.1 KB), approximately 16.2k tokens, and a symbol index with 83 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!