@@ -3,9 +3,49 @@ var $ = require('../internals/export');
33var uncurryThis = require ( '../internals/function-uncurry-this' ) ;
44var aDataView = require ( '../internals/a-data-view' ) ;
55var toIndex = require ( '../internals/to-index' ) ;
6- var packIEEE754 = require ( '../internals/ieee754' ) . pack ;
76var 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
1050var 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