Skip to content

Commit a1298dc

Browse files
authored
Merge pull request #1379 from LeviPesin/patch-1
2 parents 743f9e6 + ff1c855 commit a1298dc

File tree

2 files changed

+60
-5
lines changed

2 files changed

+60
-5
lines changed
Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,22 @@
11
'use strict';
22
var $ = require('../internals/export');
33
var uncurryThis = require('../internals/function-uncurry-this');
4-
var unpackIEEE754 = require('../internals/ieee754').unpack;
4+
5+
var pow = Math.pow;
6+
7+
var EXP_MASK16 = 31; // 2 ** 5 - 1
8+
var SIGNIFICAND_MASK16 = 1023; // 2 ** 10 - 1
9+
var MIN_SUBNORMAL16 = pow(2, -24); // 2 ** -10 * 2 ** -14
10+
var SIGNIFICAND_DENOM16 = 0.0009765625; // 2 ** -10
11+
12+
var unpackFloat16 = function (bytes) {
13+
var sign = bytes >>> 15;
14+
var exponent = bytes >>> 10 & EXP_MASK16;
15+
var significand = bytes & SIGNIFICAND_MASK16;
16+
if (exponent === EXP_MASK16) return significand === 0 ? (sign === 0 ? Infinity : -Infinity) : NaN;
17+
if (exponent === 0) return significand * (sign === 0 ? MIN_SUBNORMAL16 : -MIN_SUBNORMAL16);
18+
return pow(2, exponent - 15) * (sign === 0 ? 1 + significand * SIGNIFICAND_DENOM16 : -1 - significand * SIGNIFICAND_DENOM16);
19+
};
520

621
// eslint-disable-next-line es/no-typed-arrays -- safe
722
var getUint16 = uncurryThis(DataView.prototype.getUint16);
@@ -11,6 +26,6 @@ var getUint16 = uncurryThis(DataView.prototype.getUint16);
1126
$({ target: 'DataView', proto: true }, {
1227
getFloat16: function getFloat16(byteOffset /* , littleEndian */) {
1328
var uint16 = getUint16(this, byteOffset, arguments.length > 1 ? arguments[1] : false);
14-
return unpackIEEE754([uint16 & 0xFF, uint16 >> 8 & 0xFF], 10);
29+
return unpackFloat16(uint16);
1530
}
1631
});

packages/core-js/modules/esnext.data-view.set-float16.js

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,49 @@ var $ = require('../internals/export');
33
var uncurryThis = require('../internals/function-uncurry-this');
44
var aDataView = require('../internals/a-data-view');
55
var toIndex = require('../internals/to-index');
6-
var packIEEE754 = require('../internals/ieee754').pack;
76
var f16round = require('../internals/math-f16round');
87

8+
var pow = Math.pow;
9+
var log = Math.log;
10+
var LN2 = Math.LN2;
11+
12+
var EPSILON = 2.220446049250313e-16; // Number.EPSILON
13+
var INVERSE_EPSILON = 1 / EPSILON;
14+
15+
var roundTiesToEven = function (n) {
16+
return n + INVERSE_EPSILON - INVERSE_EPSILON;
17+
};
18+
19+
var MIN_INFINITY16 = 65520; // (2 - 2 ** -11) * 2 ** 15
20+
var MIN_NORMAL16 = 0.000061005353927612305; // (1 - 2 ** -11) * 2 ** -14
21+
var REC_MIN_SUBNORMAL16 = 16777216; // 2 ** 10 * 2 ** 14
22+
var REC_SIGNIFICAND_DENOM16 = 1024; // 2 ** 10;
23+
24+
var packFloat16 = function (value) {
25+
// eslint-disable-next-line no-self-compare -- NaN check
26+
if (value !== value) return 0x7E00; // NaN
27+
if (value === 0) return (1 / value === -Infinity) << 15; // +0 or -0
28+
29+
var neg = value < 0;
30+
if (neg) value = -value;
31+
if (value >= MIN_INFINITY16) return neg << 15 | 0x7C00; // Infinity
32+
if (value < MIN_NORMAL16) return neg << 15 | roundTiesToEven(value * REC_MIN_SUBNORMAL16); // subnormal
33+
34+
// normal
35+
var exponent = log(value) / LN2 | 0;
36+
if (exponent === -15) {
37+
// we round from a value between 2 ** -15 * (1 + 1022/1024) (the largest subnormal) and 2 ** -14 * (1 + 0/1024) (the smallest normal)
38+
// to the latter (former impossible because of the subnormal check above)
39+
return neg << 15 | REC_SIGNIFICAND_DENOM16;
40+
}
41+
var significand = roundTiesToEven((value * pow(2, -exponent) - 1) * REC_SIGNIFICAND_DENOM16);
42+
if (significand === REC_SIGNIFICAND_DENOM16) {
43+
// we round from a value between 2 ** n * (1 + 1023/1024) and 2 ** (n + 1) * (1 + 0/1024) to the latter
44+
return neg << 15 | exponent + 16 << 10;
45+
}
46+
return neg << 15 | exponent + 15 << 10 | significand;
47+
};
48+
949
// eslint-disable-next-line es/no-typed-arrays -- safe
1050
var setUint16 = uncurryThis(DataView.prototype.setUint16);
1151

@@ -15,7 +55,7 @@ $({ target: 'DataView', proto: true }, {
1555
setFloat16: function setFloat16(byteOffset, value /* , littleEndian */) {
1656
aDataView(this);
1757
var offset = toIndex(byteOffset);
18-
var bytes = packIEEE754(f16round(value), 10, 2);
19-
return setUint16(this, offset, bytes[1] << 8 | bytes[0], arguments.length > 2 ? arguments[2] : false);
58+
var bytes = packFloat16(f16round(value));
59+
return setUint16(this, offset, bytes, arguments.length > 2 ? arguments[2] : false);
2060
}
2161
});

0 commit comments

Comments
 (0)