JSFiddle - React, Tailwind, and code Playground

by Joe Nudell

HTML

<h4>Testing browser's <code>Number.prototype.toFixed</code> implementation</h4>
<p>See <a href="http://jsperf.com/native-tofixed-vs-js-tofixed">jsperf</a> for performance comparison.</p>
<p>All <a href="https://github.com/v8/v8/blob/f0c9cc0bbfd461c7f516799d9a58e9a7395f737e/test/webkit/fast/js/number-tofixed.js">test cases from V8</a> are included. Additional tests showing problems in the V8 implementation have been added.</p>
<p><div id="results"></div></p>

CSS

th {
    background-color: #99f;
}
tr {
    background-color: #ed9;
}
.passed-true {
    background-color: #9f9;
}
.passed-false {
    background-color: #f99;
}

JavaScript

// -----------------------------------------------------------
// Number.prototype.toFixed naive implementation
// per ECMA-262, 20.1.3.3
// http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf
// 
// Even this naive implementation is not all that much slower
// than the native implementation in many cases:
// http://jsperf.com/native-tofixed-vs-js-tofixed
// -----------------------------------------------------------

function toFixed(fractionDigits) {
    var x = Number(this);
    var f = fractionDigits;
    var s, m, n, k, z, k, a, b, _n, _p, _n1, _n2, _d1, _d2;

    // Undefined behaves as 0
    if (f === void 0) {
        f = 0;
    }
    
    f = Number(f);
    
    // NaN also behaves as 0
    if (f !== f) {
        f = 0;
    }
    
    // Cast to int, if not (+/-)Infinity or NaN
    f = !(f !== f || f === 1/0 || f === -1/0) ? f | 0 : f;

    if (f < 0 || f > 20) {
        throw new RangeError("fractionDigits must be in the range [0, 20]");
    }

    s = '';

    if (x < 0) {
        s = '-';
        x = -x;
    }

    if (x >= Math.pow(10, 21) || x !== x) {
        m = x.toString();
    } else {
        // A. Let n be the integer that minimizes 0 = n / 10^f - x 
        _p = Math.pow(10, f);
        // Version 1: Straightforward comparison
        _n = _p * x;
        _n1 = ~~_n;
        _n2 = _n1 + 1;
        _d1 = _n1 / _p - x;
        _d2 = _n2 / _p - x;
        _p = _d1 + _d2;
        n = (_p <= 0) ?
        // Use LTE so that _n2 is chosen when equidistant from 0
        _n2 : _n1;
        // Version 2: Only one division (algebraic equivalent)
        // _n = _p * x | 0;
        // n = (( _n + _n + 1) / _p - x - x <= 0 ? _n + 1 : _n;
        
        // B. If n = 0 return 0
        m = (n === 0) ? '0' : '' + n;
        if (f !== 0) {
            m = '' + n;
            k = m.length;
            if (k <= f) {
                z = '00000000000000000000'.substr(0, f + 1 - k);
                m = z + m;
                k = f + 1;
  ...