es.data-view.set-float16.js 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. 'use strict';
  2. var $ = require('../internals/export');
  3. var uncurryThis = require('../internals/function-uncurry-this');
  4. var aDataView = require('../internals/a-data-view');
  5. var toIndex = require('../internals/to-index');
  6. // TODO: Replace with module dependency in `core-js@4`
  7. var log2 = require('../internals/math-log2');
  8. var roundTiesToEven = require('../internals/math-round-ties-to-even');
  9. var pow = Math.pow;
  10. var MIN_INFINITY16 = 65520; // (2 - 2 ** -11) * 2 ** 15
  11. var MIN_NORMAL16 = 0.000061005353927612305; // (1 - 2 ** -11) * 2 ** -14
  12. var REC_MIN_SUBNORMAL16 = 16777216; // 2 ** 10 * 2 ** 14
  13. var REC_SIGNIFICAND_DENOM16 = 1024; // 2 ** 10;
  14. var packFloat16 = function (value) {
  15. // eslint-disable-next-line no-self-compare -- NaN check
  16. if (value !== value) return 0x7E00; // NaN
  17. if (value === 0) return (1 / value === -Infinity) << 15; // +0 or -0
  18. var neg = value < 0;
  19. if (neg) value = -value;
  20. if (value >= MIN_INFINITY16) return neg << 15 | 0x7C00; // Infinity
  21. if (value < MIN_NORMAL16) return neg << 15 | roundTiesToEven(value * REC_MIN_SUBNORMAL16); // subnormal
  22. // normal
  23. var exponent = log2(value) | 0;
  24. if (exponent === -15) {
  25. // we round from a value between 2 ** -15 * (1 + 1022/1024) (the largest subnormal) and 2 ** -14 * (1 + 0/1024) (the smallest normal)
  26. // to the latter (former impossible because of the subnormal check above)
  27. return neg << 15 | REC_SIGNIFICAND_DENOM16;
  28. }
  29. var significand = roundTiesToEven((value * pow(2, -exponent) - 1) * REC_SIGNIFICAND_DENOM16);
  30. if (significand === REC_SIGNIFICAND_DENOM16) {
  31. // we round from a value between 2 ** n * (1 + 1023/1024) and 2 ** (n + 1) * (1 + 0/1024) to the latter
  32. return neg << 15 | exponent + 16 << 10;
  33. }
  34. return neg << 15 | exponent + 15 << 10 | significand;
  35. };
  36. // eslint-disable-next-line es/no-typed-arrays -- safe
  37. var setUint16 = uncurryThis(DataView.prototype.setUint16);
  38. // `DataView.prototype.setFloat16` method
  39. // https://tc39.es/ecma262/#sec-dataview.prototype.setfloat16
  40. $({ target: 'DataView', proto: true }, {
  41. setFloat16: function setFloat16(byteOffset, value /* , littleEndian */) {
  42. aDataView(this);
  43. var offset = toIndex(byteOffset);
  44. var bytes = packFloat16(+value);
  45. return setUint16(this, offset, bytes, arguments.length > 2 ? arguments[2] : false);
  46. }
  47. });