123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899 |
- 'use strict';
- var $ = require('../internals/export');
- var uncurryThis = require('../internals/function-uncurry-this');
- var toIntegerOrInfinity = require('../internals/to-integer-or-infinity');
- var thisNumberValue = require('../internals/this-number-value');
- var $repeat = require('../internals/string-repeat');
- var log10 = require('../internals/math-log10');
- var fails = require('../internals/fails');
- var $RangeError = RangeError;
- var $String = String;
- var $isFinite = isFinite;
- var abs = Math.abs;
- var floor = Math.floor;
- var pow = Math.pow;
- var round = Math.round;
- var nativeToExponential = uncurryThis(1.0.toExponential);
- var repeat = uncurryThis($repeat);
- var stringSlice = uncurryThis(''.slice);
- // Edge 17-
- var ROUNDS_PROPERLY = nativeToExponential(-6.9e-11, 4) === '-6.9000e-11'
- // IE11- && Edge 14-
- && nativeToExponential(1.255, 2) === '1.25e+0'
- // FF86-, V8 ~ Chrome 49-50
- && nativeToExponential(12345, 3) === '1.235e+4'
- // FF86-, V8 ~ Chrome 49-50
- && nativeToExponential(25, 0) === '3e+1';
- // IE8-
- var THROWS_ON_INFINITY_FRACTION = fails(function () {
- nativeToExponential(1, Infinity);
- }) && fails(function () {
- nativeToExponential(1, -Infinity);
- });
- // Safari <11 && FF <50
- var PROPER_NON_FINITE_THIS_CHECK = !fails(function () {
- nativeToExponential(Infinity, Infinity);
- }) && !fails(function () {
- nativeToExponential(NaN, Infinity);
- });
- var FORCED = !ROUNDS_PROPERLY || !THROWS_ON_INFINITY_FRACTION || !PROPER_NON_FINITE_THIS_CHECK;
- // `Number.prototype.toExponential` method
- // https://tc39.es/ecma262/#sec-number.prototype.toexponential
- $({ target: 'Number', proto: true, forced: FORCED }, {
- toExponential: function toExponential(fractionDigits) {
- var x = thisNumberValue(this);
- if (fractionDigits === undefined) return nativeToExponential(x);
- var f = toIntegerOrInfinity(fractionDigits);
- if (!$isFinite(x)) return String(x);
- // TODO: ES2018 increased the maximum number of fraction digits to 100, need to improve the implementation
- if (f < 0 || f > 20) throw $RangeError('Incorrect fraction digits');
- if (ROUNDS_PROPERLY) return nativeToExponential(x, f);
- var s = '';
- var m = '';
- var e = 0;
- var c = '';
- var d = '';
- if (x < 0) {
- s = '-';
- x = -x;
- }
- if (x === 0) {
- e = 0;
- m = repeat('0', f + 1);
- } else {
- // this block is based on https://gist.github.com/SheetJSDev/1100ad56b9f856c95299ed0e068eea08
- // TODO: improve accuracy with big fraction digits
- var l = log10(x);
- e = floor(l);
- var n = 0;
- var w = pow(10, e - f);
- n = round(x / w);
- if (2 * x >= (2 * n + 1) * w) {
- n += 1;
- }
- if (n >= pow(10, f + 1)) {
- n /= 10;
- e += 1;
- }
- m = $String(n);
- }
- if (f !== 0) {
- m = stringSlice(m, 0, 1) + '.' + stringSlice(m, 1);
- }
- if (e === 0) {
- c = '+';
- d = '0';
- } else {
- c = e > 0 ? '+' : '-';
- d = $String(abs(e));
- }
- m += 'e' + c + d;
- return s + m;
- }
- });
|