Skip to content

Commit

Permalink
rework Math.f16round
Browse files Browse the repository at this point in the history
  • Loading branch information
zloirock committed Sep 24, 2023
1 parent fbb9091 commit 9466445
Show file tree
Hide file tree
Showing 6 changed files with 44 additions and 17 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
## Changelog
##### Unreleased
- Added [`ArrayBuffer.prototype.{ transfer, transferToFixedLength }`](https://github.com/tc39/proposal-arraybuffer-transfer) and support transferring of `ArrayBuffer`s via [`structuredClone`](https://html.spec.whatwg.org/multipage/structured-data.html#dom-structuredclone) to engines with `MessageChannel`
- Optimized [`Math.f16round`](https://github.com/tc39/proposal-float16array) polyfill
- Fixed [some conversion cases](https://github.com/petamoriken/float16/issues/1046) of `Math.f16round`
- Fully forced polyfilling of [the TC39 `Observable` proposal](https://github.com/tc39/proposal-observable) because of incompatibility with [the new WHATWG `Observable` proposal](https://github.com/WICG/observable)
- Added an extra workaround of errors with exotic environment objects in `Symbol` polyfill, [#1289](https://github.com/zloirock/core-js/issues/1289)
- Compat data improvements:
Expand Down
29 changes: 29 additions & 0 deletions packages/core-js/internals/math-f16round.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
'use strict';
var sign = require('../internals/math-sign');

var abs = Math.abs;

var EPSILON = 2.220446049250313e-16; // Number.EPSILON
var EPSILON16 = 0.0009765625; // 2 ** -10
var INVERSE_EPSILON = 1 / EPSILON;
var MAX16 = 65504; // 2 ** 15 - 2 ** 10
var MIN16 = 6.103515625e-05; // 2 ** -14

var roundTiesToEven = function (n) {
return n + INVERSE_EPSILON - INVERSE_EPSILON;
};

// `Math.f16round` method implementation
// https://github.com/tc39/proposal-float16array
module.exports = Math.f16round || function f16round(x) {
var n = +x;
var $abs = abs(n);
var $sign = sign(n);
var a, result;
if ($abs < MIN16) return $sign * roundTiesToEven($abs / MIN16 / EPSILON16) * MIN16 * EPSILON16;
a = (1 + EPSILON16 / EPSILON) * $abs;
result = a - (a - $abs);
// eslint-disable-next-line no-self-compare -- NaN check
if (result > MAX16 || result !== result) return $sign * Infinity;
return $sign * result;
};
13 changes: 7 additions & 6 deletions packages/core-js/internals/math-fround.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@
var sign = require('../internals/math-sign');

var abs = Math.abs;
var pow = Math.pow;
var EPSILON = pow(2, -52);
var EPSILON32 = pow(2, -23);
var MAX32 = pow(2, 127) * (2 - EPSILON32);
var MIN32 = pow(2, -126);

var EPSILON = 2.220446049250313e-16; // Number.EPSILON
var EPSILON32 = 1.1920928955078125e-7; // 2 ** -23;
var INVERSE_EPSILON = 1 / EPSILON;
var MAX32 = 3.4028234663852886e+38; // 2 ** 128 - 2 ** 104
var MIN32 = 1.1754943508222875e-38; // 2 ** -126;

var roundTiesToEven = function (n) {
return n + 1 / EPSILON - 1 / EPSILON;
return n + INVERSE_EPSILON - INVERSE_EPSILON;
};

// `Math.fround` method implementation
Expand Down
13 changes: 2 additions & 11 deletions packages/core-js/modules/esnext.math.f16round.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,7 @@
'use strict';
var $ = require('../internals/export');
var IEEE754 = require('../internals/ieee754');

var packIEEE754 = IEEE754.pack;
var unpackIEEE754 = IEEE754.unpack;
var $isFinite = isFinite;
var f16round = require('../internals/math-f16round');

// `Math.f16round` method
// https://github.com/tc39/proposal-float16array
$({ target: 'Math', stat: true }, {
f16round: function f16round(x) {
var n = +x;
return $isFinite(n) && n !== 0 ? unpackIEEE754(packIEEE754(n, 10, 2), 10) : n;
}
});
$({ target: 'Math', stat: true }, { f16round: f16round });
2 changes: 2 additions & 0 deletions tests/unit-global/esnext.math.f16round.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ QUnit.test('Math.f16round', assert => {
assert.same(f16round(-2.980232238769531911744490042422139897126953655970282852649688720703125e-8), -minFloat16);

assert.same(f16round(1.337), 1.3369140625);
assert.same(f16round(0.499994), 0.5);
assert.same(f16round(7.9999999), 8);

const checker = createConversionChecker(1.1);
assert.same(f16round(checker), 1.099609375, 'object wrapper');
Expand Down
2 changes: 2 additions & 0 deletions tests/unit-pure/esnext.math.f16round.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ QUnit.test('Math.f16round', assert => {
assert.same(f16round(-2.980232238769531911744490042422139897126953655970282852649688720703125e-8), -minFloat16);

assert.same(f16round(1.337), 1.3369140625);
assert.same(f16round(0.499994), 0.5);
assert.same(f16round(7.9999999), 8);

const checker = createConversionChecker(1.1);
assert.same(f16round(checker), 1.099609375, 'object wrapper');
Expand Down

0 comments on commit 9466445

Please sign in to comment.