<commit_before>/**
 * Created with JetBrains WebStorm.
 * User: Dmitry.Shahtanov
 * Date: 27.06.13
 * Time: 12:25
 * To change this template use File | Settings | File Templates.
 */

"use strict";

var NumberBase = {
    BIN:2,
    OCT:8,
    DEC:10,
    HEX:16
}

var f_PI_DIV_2 = Math.PI / 2;
var f_PI_DIV_4 = Math.PI / 4;
var f_2_DIV_PI = 2 / Math.PI;

function BesselJ( x, N ) {
    if ( N < 0 ) {
        return new cError( cErrorType.not_numeric );
    }
    if ( x === 0.0 ) {
        return new cNumber( (N == 0) ? 1 : 0 );
    }

    /*  The algorithm works only for x>0, therefore remember sign. BesselJ
     with integer order N is an even function for even N (means J(-x)=J(x))
     and an odd function for odd N (means J(-x)=-J(x)).*/
    var fSign = (N % 2 == 1 && x < 0) ? -1 : 1;
    var fX = Math.abs( x );

    var fMaxIteration = 9000000; //experimental, for to return in < 3 seconds
    var fEstimateIteration = fX * 1.5 + N;
    var bAsymptoticPossible = Math.pow( fX, 0.4 ) > N;
    if ( fEstimateIteration > fMaxIteration ) {
        if ( bAsymptoticPossible ) {
            return new cNumber( fSign * Math.sqrt( f_2_DIV_PI / fX ) * Math.cos( fX - N * f_PI_DIV_2 - f_PI_DIV_4 ) );
        }
        else {
            return new cError( cErrorType.not_numeric );
        }
    }

    var epsilon = 1.0e-15; // relative error
    var bHasfound = false, k = 0, u;

    // first used with k=1
    var m_bar, g_bar, g_bar_delta_u, g = 0, delta_u = 0, f_bar = -1;  // f_bar_k = 1/f_k, but only used for k=0

    if ( N == 0 ) {
        u = 1;
        g_bar_delta_u = 0;
        g_bar = -2 / fX;
        delta_u = g_bar_delta_u / g_bar;
        u = u + delta_u;
        g = -1 / g_bar;
        f_bar = f_bar * g;
        k = 2;
    }
    else {
        u = 0;
        for ( k = 1; k <= N - 1; k = k + 1 ) {
            m_bar = 2 * Math.fmod( k - 1, 2 ) * f_bar;
            g_bar_delta_u = -g * delta_u - m_bar * u; // alpha_k = 0.0
            g_bar = m_bar - 2 * k / fX + g;
            delta_u = g_bar_delta_u / g_bar;
            u = u + delta_u;
            g = -1 / g_bar;
            f_bar = f_bar * g;
        }
        // Step alpha_N = 1.0
        m_bar = 2 * Math.fmod( k - 1, 2 ) * f_bar;
        g_bar_delta_u = f_bar - g * delta_u - m_bar * u; // alpha_k = 1.0
        g_bar = m_bar - 2 * k / fX + g;
        delta_u = g_bar_delta_u / g_bar;
        u = u + delta_u;
        g = -1 / g_bar;
        f_bar = f_bar * g;
        k = k + 1;
    }
    // Loop until desired accuracy, always alpha_k = 0.0
    do {
        m_bar = 2 * Math.fmod( k - 1, 2 ) * f_bar;
        g_bar_delta_u = -g * delta_u - m_bar * u;
        g_bar = m_bar - 2 * k / fX + g;
        delta_u = g_bar_delta_u / g_bar;
        u = u + delta_u;
        g = -1 / g_bar;
        f_bar = f_bar * g;
        bHasfound = (Math.abs( delta_u ) <= Math.abs( u ) * epsilon);
        k = k + 1;
    }
    while ( !bHasfound && k <= fMaxIteration );
    if ( bHasfound ) {
        return new cNumber( u * fSign );
    }
    else {
        return new cError( cErrorType.not_numeric );
    }// unlikely to happen
}

function BesselI( x, n ) {
    var nMaxIteration = 20000, fXHalf = x / 2, fResult = 0,
        fEpsilon = 1.0E-30;
    if ( n < 0 ) {
        return new cError( cErrorType.not_numeric );
    }

    /*  Start the iteration without TERM(n,0), which is set here.

     TERM(n,0) = (x/2)^n / n!
     */
    var nK = 0, fTerm = 1;
    // avoid overflow in Fak(n)
    /*for ( nK = 1; nK <= n; ++nK ) {
     fTerm = fTerm / nK * fXHalf;
     }*/

    fTerm = Math.pow( fXHalf, n ) / Math.fact( n );

    fResult = fTerm;    // Start result with TERM(n,0).
    if ( fTerm !== 0 ) {
        nK = 1;
        do
        {
            fTerm = Math.pow( fXHalf, n + 2 * nK ) / ( Math.fact( nK ) * Math.fact( n + nK ) );

            /*  Calculation of TERM(n,k) from TERM(n,k-1):

             (x/2)^(n+2k)
             TERM(n,k)  =  --------------
             k! (n+k)!

             (x/2)^2 (x/2)^(n+2(k-1))
             =  --------------------------
             k (k-1)! (n+k) (n+k-1)!

             (x/2)^2     (x/2)^(n+2(k-1))
             =  --------- * ------------------
             k(n+k)      (k-1)! (n+k-1)!

             x^2/4
             =  -------- TERM(n,k-1)
             k(n+k)
             */
//            fTerm = fTerm * fXHalf / nK * fXHalf / (nK + n);
            fResult = fResult + fTerm;
            nK++;
        }
        while ( (Math.abs( fTerm ) > Math.abs( fResult ) * fEpsilon) && (nK < nMaxIteration) );

    }
    return new cNumber( fResult );
}

function Besselk0( fNum ) {
    var fRet, y;

    if ( fNum <= 2 ) {
        var fNum2 = fNum * 0.5;
        y = fNum2 * fNum2;
        fRet = -Math.log10( fNum2 ) * BesselI( fNum, 0 ) +
            ( -0.57721566 + y * ( 0.42278420 + y * ( 0.23069756 + y * ( 0.3488590e-1 + y * ( 0.262698e-2 + y * ( 0.10750e-3 + y * 0.74e-5 ) ) ) ) ) );
    }
    else {
        y = 2 / fNum;
        fRet = Math.exp( -fNum ) / Math.sqrt( fNum ) *
            ( 1.25331414 + y * ( -0.7832358e-1 + y * ( 0.2189568e-1 + y * ( -0.1062446e-1 + y * ( 0.587872e-2 + y * ( -0.251540e-2 + y * 0.53208e-3 ) ) ) ) ) );
    }

    return new cNumber( fRet );
}

function Besselk1( fNum ) {
    var fRet, y;

    if ( fNum <= 2 ) {
        var fNum2 = fNum * 0.5;
        y = fNum2 * fNum2;
        fRet = Math.log10( fNum2 ) * BesselI( fNum, 1 ) +
            ( 1 + y * ( 0.15443144 + y * ( -0.67278579 + y * ( -0.18156897 + y * ( -0.1919402e-1 + y * ( -0.110404e-2 + y * ( -0.4686e-4 ) ) ) ) ) ) ) / fNum;
    }
    else {
        y = 2 / fNum;
        fRet = Math.exp( -fNum ) / Math.sqrt( fNum ) *
            ( 1.25331414 + y * ( 0.23498619 + y * ( -0.3655620e-1 + y * ( 0.1504268e-1 + y * ( -0.780353e-2 + y * ( 0.325614e-2 + y * ( -0.68245e-3 ) ) ) ) ) ) );
    }

    return new cNumber( fRet );
}

function BesselK( fNum, nOrder ) {
    switch ( nOrder ) {
        case 0:
            return Besselk0( fNum );
        case 1:
            return Besselk1( fNum );
        default:
        {
            var fBkp;

            var fTox = 2 / fNum, fBkm = Besselk0( fNum ), fBk = Besselk1( fNum );

            if ( fBkm instanceof  cError ) {
                return fBkm;
            }
            if ( fBk instanceof  cError ) {
                return fBk;
            }

            fBkm = fBkm.getValue();
            fBk = fBk.getValue();

            for ( var n = 1; n < nOrder; n++ ) {
                fBkp = fBkm + n * fTox * fBk;
                fBkm = fBk;
                fBk = fBkp;
            }

            return new cNumber( fBk );
        }
    }
}

function Bessely0( fX ) {
    if ( fX <= 0 ) {
        return new cError( cErrorType.not_numeric );
    }
    var fMaxIteration = 9000000; // should not be reached
    if ( fX > 5.0e+6 ) { // iteration is not considerable better then approximation
        return new cNumber( Math.sqrt( 1 / Math.PI / fX ) * (Math.sin( fX ) - Math.cos( fX )) );
    }
    var epsilon = 1.0e-15, EulerGamma = 0.57721566490153286060;
    var alpha = Math.log10( fX / 2 ) + EulerGamma;
    var u = alpha;

    var k = 1, m_bar = 0, g_bar_delta_u = 0, g_bar = -2 / fX;
    var delta_u = g_bar_delta_u / g_bar, g = -1 / g_bar, f_bar = -1 * g,
        sign_alpha = 1, km1mod2, bHasFound = false;
    k = k + 1;
    do
    {
        km1mod2 = Math.fmod( k - 1, 2 );
        m_bar = (2 * km1mod2) * f_bar;
        if ( km1mod2 == 0 ) {
            alpha = 0;
        }
        else {
            alpha = sign_alpha * (4 / k);
            sign_alpha = -sign_alpha;
        }
        g_bar_delta_u = f_bar * alpha - g * delta_u - m_bar * u;
        g_bar = m_bar - (2 * k) / fX + g;
        delta_u = g_bar_delta_u / g_bar;
        u = u + delta_u;
        g = -1 / g_bar;
        f_bar = f_bar * g;
        bHasFound = (Math.abs( delta_u ) <= Math.abs( u ) * epsilon);
        k = k + 1;
    }
    while ( !bHasFound && k < fMaxIteration );
    if ( bHasFound ) {
        return new cNumber( u * f_2_DIV_PI );
    }
    else {
        return new cError( cErrorType.not_numeric );
    }
}

// See #i31656# for a commented version of this implementation, attachment #desc6
// http://www.openoffice.org/nonav/issues/showattachment.cgi/63609/Comments%20to%20the%20implementation%20of%20the%20Bessel%20functions.odt
function Bessely1( fX ) {
    if ( fX <= 0 ) {
        return new cError( cErrorType.not_numeric );
    }
    var fMaxIteration = 9000000; // should not be reached
    if ( fX > 5e+6 ) { // iteration is not considerable better then approximation
        return new cNumber( -Math.sqrt( 1 / Math.PI / fX ) * (Math.sin( fX ) + Math.cos( fX )) );
    }
    var epsilon = 1.0e-15, EulerGamma = 0.57721566490153286060, alpha = 1 / fX, f_bar = -1, u = alpha, k = 1, m_bar = 0;
    alpha = 1 - EulerGamma - Math.log10( fX / 2 );
    var g_bar_delta_u = -alpha, g_bar = -2 / fX, delta_u = g_bar_delta_u / g_bar;
    u = u + delta_u;
    var g = -1 / g_bar;
    f_bar = f_bar * g;
    var sign_alpha = -1, km1mod2, //will be (k-1) mod 2
        q, // will be (k-1) div 2
        bHasFound = false;
    k = k + 1;
    do
    {
        km1mod2 = Math.fmod( k - 1, 2 );
        m_bar = (2 * km1mod2) * f_bar;
        q = (k - 1) / 2;
        if ( km1mod2 == 0 ) { // k is odd
            alpha = sign_alpha * (1 / q + 1 / (q + 1));
            sign_alpha = -sign_alpha;
        }
        else {
            alpha = 0;
        }
        g_bar_delta_u = f_bar * alpha - g * delta_u - m_bar * u;
        g_bar = m_bar - (2 * k) / fX + g;
        delta_u = g_bar_delta_u / g_bar;
        u = u + delta_u;
        g = -1 / g_bar;
        f_bar = f_bar * g;
        bHasFound = (Math.abs( delta_u ) <= Math.abs( u ) * epsilon);
        k = k + 1;
    }
    while ( !bHasFound && k < fMaxIteration );
    if ( bHasFound ) {
        return new cNumber( -u * 2 / Math.PI );
    }
    else {
        return new cError( cErrorType.not_numeric );
    }
}

function BesselY( fNum, nOrder ) {
    switch ( nOrder ) {
        case 0:
            return Bessely0( fNum );
        case 1:
            return Bessely1( fNum );
        default:
        {
            var fByp, fTox = 2 / fNum, fBym = Bessely0( fNum ), fBy = Bessely1( fNum );

            if ( fBym instanceof  cError ) {
                return fBym;
            }
            if ( fBy instanceof  cError ) {
                return fBy;
            }

            fBym = fBym.getValue();
            fBy = fBy.getValue();

            for ( var n = 1; n < nOrder; n++ ) {
                fByp = n * fTox * fBy - fBym;
                fBym = fBy;
                fBy = fByp;
            }

            return new cNumber( fBy );
        }
    }
}

function validBINNumber( n ) {
    return rg_validBINNumber.test( n );
}

function validDEC2BINNumber( n ) {
    return rg_validDEC2BINNumber.test( n );
}

function validDEC2OCTNumber( n ) {
    return rg_validDEC2OCTNumber.test( n );
}

function validDEC2HEXNumber( n ) {
    return rg_validDEC2HEXNumber.test( n );
}

function validHEXNumber( n ) {
    return rg_validHEXNumber.test( n );
}

function validOCTNumber( n ) {
    return rg_validOCTNumber.test( n );
}

function convertFromTo( src, from, to, charLim ) {
    var res = parseInt( src, from ).toString( to );
    if ( charLim == undefined ) {
        return new cString( res.toUpperCase() );
    }
    else {
        charLim = parseInt( charLim );
        if ( charLim >= res.length ) {
            return new cString( (String.prototype.repeat( '0', charLim - res.length ) + res).toUpperCase() );
        }
        else {
            return new cError( cErrorType.not_numeric );
        }
    }
}

function Complex( r, i, suffix ) {
    if ( arguments.length == 1 ) {
        return this.ParseString( arguments[0] );
    }
    else {
        this.real = r;
        this.img = i;
        this.suffix = suffix ? suffix : "i";
        return this;
    }
}

Complex.prototype = {

    constructor:Complex,
    toString:function () {
        var res = [];
        var hasImag = this.img != 0,
            hasReal = !hasImag || (this.real != 0);

        if ( hasReal ) {

            res.push( this.real );
        }
        if ( hasImag ) {
            if ( this.img == 1 ) {
                if ( hasReal ) {
                    res.push( '+' );
                }
            }
            else if ( this.img == -1 ) {
                res.push( "-" );
            }
            else {
                this.img > 0 && hasReal ? res.push( "+" + this.img ) : res.push( this.img );
            }
            res.push( this.suffix ? this.suffix : "i" );
        }
        return res.join( "" );
    },
    Real:function () {
        return this.real;
    },
    Imag:function () {
        return this.img;
    },
    Abs:function () {
        return Math.sqrt( this.real * this.real + this.img * this.img );
    },
    Arg:function () {
        if ( this.real == 0.0 && this.img == 0.0 ) {
            return Number.NaN;
        }

        var phi = Math.acos( this.real / this.Abs() );

        if ( this.img < 0.0 ) {
            phi = -phi;
        }

        return phi;
    },
    Conj:function () {
        var c = new Complex( this.real, -this.img, this.suffix );
        return c.toString();
    },
    Cos:function () {
        if ( i ) {
            var a = Math.cos( this.real ) * Math.cosh( this.img );
            this.img = -( Math.sin( this.real ) * Math.sinh( this.img ) );
            this.real = a;
        }
        else
            this.real = cos( this.real );
    },
    Sin:function () {
        if ( this.img ) {
            var a = Math.sin( this.real ) * Math.cosh( this.img );
            this.img = Math.cos( this.real ) * Math.sinh( this.img );
            this.real = a;
        }
        else {
            this.real = Math.sin( this.real );
        }
    },
    Div:function ( comp ) {

        var a = this.real, b = this.img,
            c = comp.real, d = comp.img,
            f = 1 / (c * c + d * d)

        return new Complex( (a * c + b * d) * f, (b * c - a * d) * f, this.suffix );

    },
    Exp:function () {

        var e = Math.exp( this.real ),
            c = Math.cos( this.img ),
            s = Math.sin( this.img );

        this.real = e * c;
        this.img = e * s;

    },
    Ln:function () {

        var abs = this.Abs(),
            arg = this.Arg();

        this.real = Math.ln( abs );
        this.img = arg;

    },
    Log10:function () {

        var c = new Complex( Math.ln( 10 ), 0 )
        this.Ln();
        c = this.Div( c );

        this.real = c.real;
        this.img = c.img;

    },
    Log2:function () {

        var c = new Complex( Math.ln( 2 ), 0 )
        this.Ln();
        c = this.Div( c );

        this.real = c.real;
        this.img = c.img;

    },
    Power:function ( power ) {

        if ( this.real == 0 && this.img == 0 ) {
            if ( power > 0 ) {
                this.real = this.img = 0;
                return true;
            }
            else
                return false;
        }
        else {

            var p = this.Abs(),
                phi;

            phi = Math.acos( this.real / p );
            if ( i < 0 ) {
                phi = -phi;
            }

            p = Math.pow( p, power );
            phi *= power;

            this.real = Math.cos( phi ) * p;
            this.img = Math.sin( phi ) * p;

            return true;
        }

    },
    Product:function ( comp ) {

        var a = this.real, b = this.img,
            c = comp.real, d = comp.img;

        this.real = a * c - b * d;
        this.img = a * d + b * c;

    },
    SQRT:function () {

        if ( this.real || this.img ) {
            var abs = this.Abs(),
                arg = this.Arg();

            this.real = Math.sqrt( abs ) * Math.cos( arg / 2 );
            this.img = Math.sqrt( abs ) * Math.sin( arg / 2 );

        }

    },
    Sub:function ( comp ) {

        this.real -= comp.real;
        this.img -= comp.img;

    },
    Sum:function ( comp ) {

        this.real += comp.real;
        this.img += comp.img;

    },
    isImagUnit:function ( c ) {
        return c == 'i' || c == 'j';
    },
    parseComplexStr:function ( s ) {
        var match = rg_complex_number.xexec( s ), r, i, suf;
        if ( match ) {
            r = match["real"];
            i = match["img"];

            if ( !(r || i) ) {
                return new cError( cErrorType.not_numeric );
            }

            if ( i ) {
                suf = i[i.length - 1];
                i = i.substr( 0, i.length - 1 );
                if ( i.length == 1 && (i[0] == "-" || i[0] == "+" ) ) {
                    i = parseFloat( i + "1" );
                }
                else {
                    i = parseFloat( i );
                }
            }
            else {
                i = 0;
            }

            if ( r ) {
                r = parseFloat( r );
            }
            else {
                r = 0;
            }

            return new Complex( r, i, suf ? suf : "i" );

        }
        else {
            return new cError( cErrorType.not_numeric );
        }
    },
    ParseString:function ( rStr ) {

        var pStr = {pStr:rStr}, f = {f:undefined};

        if ( this.isImagUnit( pStr.pStr[0] ) && rStr.length == 1 ) {
            this.real = 0;
            this.img = 1;
            this.suffix = pStr;
            return this;
        }

        if ( !this.ParseDouble( pStr, f ) ) {
            return new cError( cErrorType.not_numeric );
        }

        switch ( pStr.pStr[0] ) {
            case '-':   // imag part follows
            case '+':
            {
                var r = f.f;

                if ( this.isImagUnit( pStr.pStr[ 1 ] ) ) {
                    this.c = pStr.pStr[ 1 ];
                    if ( pStr.pStr[ 2 ] === undefined ) {
                        this.real = f.f;
                        this.img = ( pStr.pStr[0] == '+' ) ? 1.0 : -1.0;
                        return this;
                    }
                }
                else if ( this.ParseDouble( pStr, f ) && this.isImagUnit( pStr.pStr[0] ) ) {
                    this.c = pStr.pStr;
                    if ( pStr.pStr[2] === undefined ) {
                        this.real = r;
                        this.img = f.f;
                        return this;
                    }
                }
                break;
            }
            case 'j':
            case 'i':
                this.c = pStr;
                if ( pStr.pStr[1] === undefined ) {
                    this.img = f.f;
                    this.real = 0.0;
                    return this;
                }
                break;
            case 0:     // only real-part
                this.real = f.f;
                this.img = 0.0;
                return this;
        }
        return new cError( cErrorType.not_numeric );
    },
    ParseDouble:function ( rp, rRet ) {

        function IsNum( c ) {
            return c >= '0' && c <= '9';
        }


        function IsComma( c ) {
            return c == '.' || c == ',';
        }


        function IsExpStart( c ) {
            return c == 'e' || c == 'E';
        }


        function IsImagUnit( c ) {
            return c == 'i' || c == 'j';
        }

        var fInt = 0.0,
            fFrac = 0.0,
            fMult = 0.1, // multiplier to multiply digits with, when adding fractional ones
            nExp = 0,
            nMaxExp = 307,
            nDigCnt = 18, // max. number of digits to read in, rest doesn't matter
            State = {
                S_End:0,
                S_Sign:1,
                S_IntStart:2,
                S_Int:3,
                S_IgnoreIntDigs:4,
                S_Frac:5,
                S_IgnoreFracDigs:6,
                S_ExpSign:7,
                S_Exp:8
            }, eS = State.S_Sign,
            bNegNum = false,
            bNegExp = false,
            p = rp.pStr, c, i = 0;

        while ( eS ) {
            c = p[i];
            switch ( eS ) {
                case State.S_Sign:
                    if ( IsNum( c ) ) {
                        fInt = parseFloat( c );
                        nDigCnt--;
                        eS = State.S_Int;
                    }
                    else if ( c == '-' ) {
                        bNegNum = true;
                        eS = State.S_IntStart;
                    }
                    else if ( c == '+' ) {
                        eS = State.S_IntStart;
                    }
                    else if ( IsComma( c ) ) {
                        eS = State.S_Frac;
                    }
                    else {
                        return false;
                    }
                    break;
                case State.S_IntStart:
                    if ( IsNum( c ) ) {
                        fInt = parseFloat( c );
                        nDigCnt--;
                        eS = State.S_Int;
                    }
                    else if ( IsComma( c ) ) {
                        eS = State.S_Frac;
                    }
                    else if ( IsImagUnit( c ) ) {
                        rRet.f = 0.0;
                        return true;
                    }
                    else {
                        return false;
                    }
                    break;
                case State.S_Int:
                    if ( IsNum( c ) ) {
                        fInt *= 10.0;
                        fInt += parseFloat( c );
                        nDigCnt--;
                        if ( !nDigCnt ) {
                            eS = State.S_IgnoreIntDigs;
                        }
                    }
                    else if ( IsComma( c ) ) {
                        eS = State.S_Frac;
                    }
                    else if ( IsExpStart( c ) ) {
                        eS = State.S_ExpSign;
                    }
                    else {
                        eS = State.S_End;
                    }
                    break;
                case State.S_IgnoreIntDigs:
                    if ( IsNum( c ) ) {
                        nExp++;
                    }     // just multiply num with 10... ;-)
                    else if ( IsComma( c ) ) {
                        eS = State.S_Frac;
                    }
                    else if ( IsExpStart( c ) ) {
                        eS = State.S_ExpSign;
                    }
                    else {
                        eS = State.S_End;
                    }
                    break;
                case State.S_Frac:
                    if ( IsNum( c ) ) {
                        fFrac += parseFloat( c ) * fMult;
                        nDigCnt--;
                        if ( nDigCnt ) {
                            fMult *= 0.1;
                        }
                        else {
                            eS = State.S_IgnoreFracDigs;
                        }
                    }
                    else if ( IsExpStart( c ) ) {
                        eS = State.S_ExpSign;
                    }
                    else {
                        eS = State.S_End;
                    }
                    break;
                case State.S_IgnoreFracDigs:
                    if ( IsExpStart( c ) ) {
                        eS = State.S_ExpSign;
                    }
                    else if ( !IsNum( c ) ) {
                        eS = State.S_End;
                    }
                    break;
                case State.S_ExpSign:
                    if ( IsNum( c ) ) {
                        nExp = parseFloat( c );
                        eS = State.S_Exp;
                    }
                    else if ( c == '-' ) {
                        bNegExp = true;
                        eS = State.S_Exp;
                    }
                    else if ( c != '+' ) {
                        eS = State.S_End;
                    }
                    break;
                case State.S_Exp:
                    if ( IsNum( c ) ) {
                        nExp *= 10;
                        nExp += parseFloat( c );
                        if ( nExp > nMaxExp ) {
                            return false;
                        }
                    }
                    else {
                        eS = State.S_End;
                    }
                    break;
                case State.S_End:     // to avoid compiler warning
                    break;      // loop exits anyway
            }

            i++;
        }

        i--;        // set pointer back to last
        rp.pStr = p.substr( i );

        fInt += fFrac;
        var nLog10 = Math.log10( fInt );

        if ( bNegExp ) {
            nExp = -nExp;
        }

        if ( nLog10 + nExp > nMaxExp ) {
            return false;
        }

        fInt = fInt * Math.pow( 10.0, nExp );

        if ( bNegNum ) {
            fInt = -fInt;
        }<commit_msg>fix: Bug 26172 - Расчет функции производится если комплексное число имеет некорректный формат<commit_after>/**
 * Created with JetBrains WebStorm.
 * User: Dmitry.Shahtanov
 * Date: 27.06.13
 * Time: 12:25
 * To change this template use File | Settings | File Templates.
 */

"use strict";

var NumberBase = {
    BIN:2,
    OCT:8,
    DEC:10,
    HEX:16
}

var f_PI_DIV_2 = Math.PI / 2;
var f_PI_DIV_4 = Math.PI / 4;
var f_2_DIV_PI = 2 / Math.PI;

function BesselJ( x, N ) {
    if ( N < 0 ) {
        return new cError( cErrorType.not_numeric );
    }
    if ( x === 0.0 ) {
        return new cNumber( (N == 0) ? 1 : 0 );
    }

    /*  The algorithm works only for x>0, therefore remember sign. BesselJ
     with integer order N is an even function for even N (means J(-x)=J(x))
     and an odd function for odd N (means J(-x)=-J(x)).*/
    var fSign = (N % 2 == 1 && x < 0) ? -1 : 1;
    var fX = Math.abs( x );

    var fMaxIteration = 9000000; //experimental, for to return in < 3 seconds
    var fEstimateIteration = fX * 1.5 + N;
    var bAsymptoticPossible = Math.pow( fX, 0.4 ) > N;
    if ( fEstimateIteration > fMaxIteration ) {
        if ( bAsymptoticPossible ) {
            return new cNumber( fSign * Math.sqrt( f_2_DIV_PI / fX ) * Math.cos( fX - N * f_PI_DIV_2 - f_PI_DIV_4 ) );
        }
        else {
            return new cError( cErrorType.not_numeric );
        }
    }

    var epsilon = 1.0e-15; // relative error
    var bHasfound = false, k = 0, u;

    // first used with k=1
    var m_bar, g_bar, g_bar_delta_u, g = 0, delta_u = 0, f_bar = -1;  // f_bar_k = 1/f_k, but only used for k=0

    if ( N == 0 ) {
        u = 1;
        g_bar_delta_u = 0;
        g_bar = -2 / fX;
        delta_u = g_bar_delta_u / g_bar;
        u = u + delta_u;
        g = -1 / g_bar;
        f_bar = f_bar * g;
        k = 2;
    }
    else {
        u = 0;
        for ( k = 1; k <= N - 1; k = k + 1 ) {
            m_bar = 2 * Math.fmod( k - 1, 2 ) * f_bar;
            g_bar_delta_u = -g * delta_u - m_bar * u; // alpha_k = 0.0
            g_bar = m_bar - 2 * k / fX + g;
            delta_u = g_bar_delta_u / g_bar;
            u = u + delta_u;
            g = -1 / g_bar;
            f_bar = f_bar * g;
        }
        // Step alpha_N = 1.0
        m_bar = 2 * Math.fmod( k - 1, 2 ) * f_bar;
        g_bar_delta_u = f_bar - g * delta_u - m_bar * u; // alpha_k = 1.0
        g_bar = m_bar - 2 * k / fX + g;
        delta_u = g_bar_delta_u / g_bar;
        u = u + delta_u;
        g = -1 / g_bar;
        f_bar = f_bar * g;
        k = k + 1;
    }
    // Loop until desired accuracy, always alpha_k = 0.0
    do {
        m_bar = 2 * Math.fmod( k - 1, 2 ) * f_bar;
        g_bar_delta_u = -g * delta_u - m_bar * u;
        g_bar = m_bar - 2 * k / fX + g;
        delta_u = g_bar_delta_u / g_bar;
        u = u + delta_u;
        g = -1 / g_bar;
        f_bar = f_bar * g;
        bHasfound = (Math.abs( delta_u ) <= Math.abs( u ) * epsilon);
        k = k + 1;
    }
    while ( !bHasfound && k <= fMaxIteration );
    if ( bHasfound ) {
        return new cNumber( u * fSign );
    }
    else {
        return new cError( cErrorType.not_numeric );
    }// unlikely to happen
}

function BesselI( x, n ) {
    var nMaxIteration = 20000, fXHalf = x / 2, fResult = 0,
        fEpsilon = 1.0E-30;
    if ( n < 0 ) {
        return new cError( cErrorType.not_numeric );
    }

    /*  Start the iteration without TERM(n,0), which is set here.

     TERM(n,0) = (x/2)^n / n!
     */
    var nK = 0, fTerm = 1;
    // avoid overflow in Fak(n)
    /*for ( nK = 1; nK <= n; ++nK ) {
     fTerm = fTerm / nK * fXHalf;
     }*/

    fTerm = Math.pow( fXHalf, n ) / Math.fact( n );

    fResult = fTerm;    // Start result with TERM(n,0).
    if ( fTerm !== 0 ) {
        nK = 1;
        do
        {
            fTerm = Math.pow( fXHalf, n + 2 * nK ) / ( Math.fact( nK ) * Math.fact( n + nK ) );

            /*  Calculation of TERM(n,k) from TERM(n,k-1):

             (x/2)^(n+2k)
             TERM(n,k)  =  --------------
             k! (n+k)!

             (x/2)^2 (x/2)^(n+2(k-1))
             =  --------------------------
             k (k-1)! (n+k) (n+k-1)!

             (x/2)^2     (x/2)^(n+2(k-1))
             =  --------- * ------------------
             k(n+k)      (k-1)! (n+k-1)!

             x^2/4
             =  -------- TERM(n,k-1)
             k(n+k)
             */
//            fTerm = fTerm * fXHalf / nK * fXHalf / (nK + n);
            fResult = fResult + fTerm;
            nK++;
        }
        while ( (Math.abs( fTerm ) > Math.abs( fResult ) * fEpsilon) && (nK < nMaxIteration) );

    }
    return new cNumber( fResult );
}

function Besselk0( fNum ) {
    var fRet, y;

    if ( fNum <= 2 ) {
        var fNum2 = fNum * 0.5;
        y = fNum2 * fNum2;
        fRet = -Math.log10( fNum2 ) * BesselI( fNum, 0 ) +
            ( -0.57721566 + y * ( 0.42278420 + y * ( 0.23069756 + y * ( 0.3488590e-1 + y * ( 0.262698e-2 + y * ( 0.10750e-3 + y * 0.74e-5 ) ) ) ) ) );
    }
    else {
        y = 2 / fNum;
        fRet = Math.exp( -fNum ) / Math.sqrt( fNum ) *
            ( 1.25331414 + y * ( -0.7832358e-1 + y * ( 0.2189568e-1 + y * ( -0.1062446e-1 + y * ( 0.587872e-2 + y * ( -0.251540e-2 + y * 0.53208e-3 ) ) ) ) ) );
    }

    return new cNumber( fRet );
}

function Besselk1( fNum ) {
    var fRet, y;

    if ( fNum <= 2 ) {
        var fNum2 = fNum * 0.5;
        y = fNum2 * fNum2;
        fRet = Math.log10( fNum2 ) * BesselI( fNum, 1 ) +
            ( 1 + y * ( 0.15443144 + y * ( -0.67278579 + y * ( -0.18156897 + y * ( -0.1919402e-1 + y * ( -0.110404e-2 + y * ( -0.4686e-4 ) ) ) ) ) ) ) / fNum;
    }
    else {
        y = 2 / fNum;
        fRet = Math.exp( -fNum ) / Math.sqrt( fNum ) *
            ( 1.25331414 + y * ( 0.23498619 + y * ( -0.3655620e-1 + y * ( 0.1504268e-1 + y * ( -0.780353e-2 + y * ( 0.325614e-2 + y * ( -0.68245e-3 ) ) ) ) ) ) );
    }

    return new cNumber( fRet );
}

function BesselK( fNum, nOrder ) {
    switch ( nOrder ) {
        case 0:
            return Besselk0( fNum );
        case 1:
            return Besselk1( fNum );
        default:
        {
            var fBkp;

            var fTox = 2 / fNum, fBkm = Besselk0( fNum ), fBk = Besselk1( fNum );

            if ( fBkm instanceof  cError ) {
                return fBkm;
            }
            if ( fBk instanceof  cError ) {
                return fBk;
            }

            fBkm = fBkm.getValue();
            fBk = fBk.getValue();

            for ( var n = 1; n < nOrder; n++ ) {
                fBkp = fBkm + n * fTox * fBk;
                fBkm = fBk;
                fBk = fBkp;
            }

            return new cNumber( fBk );
        }
    }
}

function Bessely0( fX ) {
    if ( fX <= 0 ) {
        return new cError( cErrorType.not_numeric );
    }
    var fMaxIteration = 9000000; // should not be reached
    if ( fX > 5.0e+6 ) { // iteration is not considerable better then approximation
        return new cNumber( Math.sqrt( 1 / Math.PI / fX ) * (Math.sin( fX ) - Math.cos( fX )) );
    }
    var epsilon = 1.0e-15, EulerGamma = 0.57721566490153286060;
    var alpha = Math.log10( fX / 2 ) + EulerGamma;
    var u = alpha;

    var k = 1, m_bar = 0, g_bar_delta_u = 0, g_bar = -2 / fX;
    var delta_u = g_bar_delta_u / g_bar, g = -1 / g_bar, f_bar = -1 * g,
        sign_alpha = 1, km1mod2, bHasFound = false;
    k = k + 1;
    do
    {
        km1mod2 = Math.fmod( k - 1, 2 );
        m_bar = (2 * km1mod2) * f_bar;
        if ( km1mod2 == 0 ) {
            alpha = 0;
        }
        else {
            alpha = sign_alpha * (4 / k);
            sign_alpha = -sign_alpha;
        }
        g_bar_delta_u = f_bar * alpha - g * delta_u - m_bar * u;
        g_bar = m_bar - (2 * k) / fX + g;
        delta_u = g_bar_delta_u / g_bar;
        u = u + delta_u;
        g = -1 / g_bar;
        f_bar = f_bar * g;
        bHasFound = (Math.abs( delta_u ) <= Math.abs( u ) * epsilon);
        k = k + 1;
    }
    while ( !bHasFound && k < fMaxIteration );
    if ( bHasFound ) {
        return new cNumber( u * f_2_DIV_PI );
    }
    else {
        return new cError( cErrorType.not_numeric );
    }
}

// See #i31656# for a commented version of this implementation, attachment #desc6
// http://www.openoffice.org/nonav/issues/showattachment.cgi/63609/Comments%20to%20the%20implementation%20of%20the%20Bessel%20functions.odt
function Bessely1( fX ) {
    if ( fX <= 0 ) {
        return new cError( cErrorType.not_numeric );
    }
    var fMaxIteration = 9000000; // should not be reached
    if ( fX > 5e+6 ) { // iteration is not considerable better then approximation
        return new cNumber( -Math.sqrt( 1 / Math.PI / fX ) * (Math.sin( fX ) + Math.cos( fX )) );
    }
    var epsilon = 1.0e-15, EulerGamma = 0.57721566490153286060, alpha = 1 / fX, f_bar = -1, u = alpha, k = 1, m_bar = 0;
    alpha = 1 - EulerGamma - Math.log10( fX / 2 );
    var g_bar_delta_u = -alpha, g_bar = -2 / fX, delta_u = g_bar_delta_u / g_bar;
    u = u + delta_u;
    var g = -1 / g_bar;
    f_bar = f_bar * g;
    var sign_alpha = -1, km1mod2, //will be (k-1) mod 2
        q, // will be (k-1) div 2
        bHasFound = false;
    k = k + 1;
    do
    {
        km1mod2 = Math.fmod( k - 1, 2 );
        m_bar = (2 * km1mod2) * f_bar;
        q = (k - 1) / 2;
        if ( km1mod2 == 0 ) { // k is odd
            alpha = sign_alpha * (1 / q + 1 / (q + 1));
            sign_alpha = -sign_alpha;
        }
        else {
            alpha = 0;
        }
        g_bar_delta_u = f_bar * alpha - g * delta_u - m_bar * u;
        g_bar = m_bar - (2 * k) / fX + g;
        delta_u = g_bar_delta_u / g_bar;
        u = u + delta_u;
        g = -1 / g_bar;
        f_bar = f_bar * g;
        bHasFound = (Math.abs( delta_u ) <= Math.abs( u ) * epsilon);
        k = k + 1;
    }
    while ( !bHasFound && k < fMaxIteration );
    if ( bHasFound ) {
        return new cNumber( -u * 2 / Math.PI );
    }
    else {
        return new cError( cErrorType.not_numeric );
    }
}

function BesselY( fNum, nOrder ) {
    switch ( nOrder ) {
        case 0:
            return Bessely0( fNum );
        case 1:
            return Bessely1( fNum );
        default:
        {
            var fByp, fTox = 2 / fNum, fBym = Bessely0( fNum ), fBy = Bessely1( fNum );

            if ( fBym instanceof  cError ) {
                return fBym;
            }
            if ( fBy instanceof  cError ) {
                return fBy;
            }

            fBym = fBym.getValue();
            fBy = fBy.getValue();

            for ( var n = 1; n < nOrder; n++ ) {
                fByp = n * fTox * fBy - fBym;
                fBym = fBy;
                fBy = fByp;
            }

            return new cNumber( fBy );
        }
    }
}

function validBINNumber( n ) {
    return rg_validBINNumber.test( n );
}

function validDEC2BINNumber( n ) {
    return rg_validDEC2BINNumber.test( n );
}

function validDEC2OCTNumber( n ) {
    return rg_validDEC2OCTNumber.test( n );
}

function validDEC2HEXNumber( n ) {
    return rg_validDEC2HEXNumber.test( n );
}

function validHEXNumber( n ) {
    return rg_validHEXNumber.test( n );
}

function validOCTNumber( n ) {
    return rg_validOCTNumber.test( n );
}

function convertFromTo( src, from, to, charLim ) {
    var res = parseInt( src, from ).toString( to );
    if ( charLim == undefined ) {
        return new cString( res.toUpperCase() );
    }
    else {
        charLim = parseInt( charLim );
        if ( charLim >= res.length ) {
            return new cString( (String.prototype.repeat( '0', charLim - res.length ) + res).toUpperCase() );
        }
        else {
            return new cError( cErrorType.not_numeric );
        }
    }
}

function Complex( r, i, suffix ) {
    if ( arguments.length == 1 ) {
        return this.ParseString( arguments[0] );
    }
    else {
        this.real = r;
        this.img = i;
        this.suffix = suffix ? suffix : "i";
        return this;
    }
}

Complex.prototype = {

    constructor:Complex,
    toString:function () {
        var res = [];
        var hasImag = this.img != 0,
            hasReal = !hasImag || (this.real != 0);

        if ( hasReal ) {

            res.push( this.real );
        }
        if ( hasImag ) {
            if ( this.img == 1 ) {
                if ( hasReal ) {
                    res.push( '+' );
                }
            }
            else if ( this.img == -1 ) {
                res.push( "-" );
            }
            else {
                this.img > 0 && hasReal ? res.push( "+" + this.img ) : res.push( this.img );
            }
            res.push( this.suffix ? this.suffix : "i" );
        }
        return res.join( "" );
    },
    Real:function () {
        return this.real;
    },
    Imag:function () {
        return this.img;
    },
    Abs:function () {
        return Math.sqrt( this.real * this.real + this.img * this.img );
    },
    Arg:function () {
        if ( this.real == 0.0 && this.img == 0.0 ) {
            return Number.NaN;
        }

        var phi = Math.acos( this.real / this.Abs() );

        if ( this.img < 0.0 ) {
            phi = -phi;
        }

        return phi;
    },
    Conj:function () {
        var c = new Complex( this.real, -this.img, this.suffix );
        return c.toString();
    },
    Cos:function () {
        if ( i ) {
            var a = Math.cos( this.real ) * Math.cosh( this.img );
            this.img = -( Math.sin( this.real ) * Math.sinh( this.img ) );
            this.real = a;
        }
        else
            this.real = cos( this.real );
    },
    Sin:function () {
        if ( this.img ) {
            var a = Math.sin( this.real ) * Math.cosh( this.img );
            this.img = Math.cos( this.real ) * Math.sinh( this.img );
            this.real = a;
        }
        else {
            this.real = Math.sin( this.real );
        }
    },
    Div:function ( comp ) {

        var a = this.real, b = this.img,
            c = comp.real, d = comp.img,
            f = 1 / (c * c + d * d)

        return new Complex( (a * c + b * d) * f, (b * c - a * d) * f, this.suffix );

    },
    Exp:function () {

        var e = Math.exp( this.real ),
            c = Math.cos( this.img ),
            s = Math.sin( this.img );

        this.real = e * c;
        this.img = e * s;

    },
    Ln:function () {

        var abs = this.Abs(),
            arg = this.Arg();

        this.real = Math.ln( abs );
        this.img = arg;

    },
    Log10:function () {

        var c = new Complex( Math.ln( 10 ), 0 )
        this.Ln();
        c = this.Div( c );

        this.real = c.real;
        this.img = c.img;

    },
    Log2:function () {

        var c = new Complex( Math.ln( 2 ), 0 )
        this.Ln();
        c = this.Div( c );

        this.real = c.real;
        this.img = c.img;

    },
    Power:function ( power ) {

        if ( this.real == 0 && this.img == 0 ) {
            if ( power > 0 ) {
                this.real = this.img = 0;
                return true;
            }
            else
                return false;
        }
        else {

            var p = this.Abs(),
                phi;

            phi = Math.acos( this.real / p );
            if ( i < 0 ) {
                phi = -phi;
            }

            p = Math.pow( p, power );
            phi *= power;

            this.real = Math.cos( phi ) * p;
            this.img = Math.sin( phi ) * p;

            return true;
        }

    },
    Product:function ( comp ) {

        var a = this.real, b = this.img,
            c = comp.real, d = comp.img;

        this.real = a * c - b * d;
        this.img = a * d + b * c;

    },
    SQRT:function () {

        if ( this.real || this.img ) {
            var abs = this.Abs(),
                arg = this.Arg();

            this.real = Math.sqrt( abs ) * Math.cos( arg / 2 );
            this.img = Math.sqrt( abs ) * Math.sin( arg / 2 );

        }

    },
    Sub:function ( comp ) {

        this.real -= comp.real;
        this.img -= comp.img;

    },
    Sum:function ( comp ) {

        this.real += comp.real;
        this.img += comp.img;

    },
    isImagUnit:function ( c ) {
        return c == 'i' || c == 'j';
    },
    parseComplexStr:function ( s ) {
        var match = rg_complex_number.xexec( s ), r, i, suf;
        if ( match ) {
            r = match["real"];
            i = match["img"];

            if ( !(r || i) ) {
                return new cError( cErrorType.not_numeric );
            }

            if ( i ) {
                suf = i[i.length - 1];
                i = i.substr( 0, i.length - 1 );
                if ( i.length == 1 && (i[0] == "-" || i[0] == "+" ) ) {
                    i = parseFloat( i + "1" );
                }
                else {
                    i = parseFloat( i );
                }
            }
            else {
                i = 0;
            }

            if ( r ) {
                r = parseFloat( r );
            }
            else {
                r = 0;
            }

            return new Complex( r, i, suf ? suf : "i" );

        }
        else {
            return new cError( cErrorType.not_numeric );
        }
    },
    ParseString:function ( rStr ) {

        var pStr = {pStr:rStr}, f = {f:undefined};

        if ( this.isImagUnit( pStr.pStr[0] ) && rStr.length == 1 ) {
            this.real = 0;
            this.img = 1;
            this.suffix = pStr;
            return this;
        }

        if ( !this.ParseDouble( pStr, f ) ) {
            return new cError( cErrorType.not_numeric );
        }

        switch ( pStr.pStr[0]+"" ) {
            case '-':   // imag part follows
            case '+':
            {
                var r = f.f;

                if ( this.isImagUnit( pStr.pStr[ 1 ] ) ) {
                    this.c = pStr.pStr[ 1 ];
                    if ( pStr.pStr[ 2 ] === undefined ) {
                        this.real = f.f;
                        this.img = ( pStr.pStr[0] == '+' ) ? 1.0 : -1.0;
                        return this;
                    }
                }
                else if ( this.ParseDouble( pStr, f ) && this.isImagUnit( pStr.pStr[0] ) ) {
                    this.c = pStr.pStr;
                    if ( pStr.pStr[2] === undefined ) {
                        this.real = r;
                        this.img = f.f;
                        return this;
                    }
                }
                break;
            }
            case 'j':
            case 'i':
                this.c = pStr;
                if ( pStr.pStr[1] === undefined ) {
                    this.img = f.f;
                    this.real = 0.0;
                    return this;
                }
                break;
            case "undefined":     // only real-part
                this.real = f.f;
                this.img = 0.0;
                return this;
        }
        return new cError( cErrorType.not_numeric );
    },
    ParseDouble:function ( rp, rRet ) {

        function isnum( c ) {
            return c >= '0' && c <= '9';
        }


        function iscomma( c ) {
            return c == '.' || c == ',';
        }


        function isexpstart( c ) {
            return c == 'e' || c == 'E';
        }


        function isimagunit( c ) {
            return c == 'i' || c == 'j';
        }

        var fInt = 0.0,
            fFrac = 0.0,
            fMult = 0.1, // multiplier to multiply digits with, when adding fractional ones
            nExp = 0,
            nMaxExp = 307,
            nDigCnt = 18, // max. number of digits to read in, rest doesn't matter
            State = {
                end:0,
                sign:1,
                intstart:2,
                int:3,
                ignoreintdigs:4,
                frac:5,
                ignorefracdigs:6,
                expsign:7,
                exp:8
            }, eS = State.sign,
            bNegNum = false,
            bNegExp = false,
            p = rp.pStr, c, i = 0;

        while ( eS ) {
            c = p[i];
            switch ( eS ) {
                case State.sign:
                    if ( isnum( c ) ) {
                        fInt = parseFloat( c );
                        nDigCnt--;
                        eS = State.int;
                    }
                    else if ( c == '-' ) {
                        bNegNum = true;
                        eS = State.intstart;
                    }
                    else if ( c == '+' ) {
                        eS = State.intstart;
                    }
                    else if ( iscomma( c ) ) {
                        eS = State.frac;
                    }
                    else {
                        return false;
                    }
                    break;
                case State.intstart:
                    if ( isnum( c ) ) {
                        fInt = parseFloat( c );
                        nDigCnt--;
                        eS = State.int;
                    }
                    else if ( iscomma( c ) ) {
                        eS = State.frac;
                    }
                    else if ( isimagunit( c ) ) {
                        rRet.f = 0.0;
                        return true;
                    }
                    else {
                        return false;
                    }
                    break;
                case State.int:
                    if ( isnum( c ) ) {
                        fInt *= 10.0;
                        fInt += parseFloat( c );
                        nDigCnt--;
                        if ( !nDigCnt ) {
                            eS = State.ignoreintdigs;
                        }
                    }
                    else if ( iscomma( c ) ) {
                        eS = State.frac;
                    }
                    else if ( isexpstart( c ) ) {
                        eS = State.expsign;
                    }
                    else {
                        eS = State.end;
                    }
                    break;
                case State.ignoreintdigs:
                    if ( isnum( c ) ) {
                        nExp++;
                    }     // just multiply num with 10... ;-)
                    else if ( iscomma( c ) ) {
                        eS = State.frac;
                    }
                    else if ( isexpstart( c ) ) {
                        eS = State.expsign;
                    }
                    else {
                        eS = State.end;
                    }
                    break;
                case State.frac:
                    if ( isnum( c ) ) {
                        fFrac += parseFloat( c ) * fMult;
                        nDigCnt--;
                        if ( nDigCnt ) {
                            fMult *= 0.1;
                        }
                        else {
                            eS = State.ignorefracdigs;
                        }
                    }
                    else if ( isexpstart( c ) ) {
                        eS = State.expsign;
                    }
                    else {
                        eS = State.end;
                    }
                    break;
                case State.ignorefracdigs:
                    if ( isexpstart( c ) ) {
                        eS = State.expsign;
                    }
                    else if ( !isnum( c ) ) {
                        eS = State.end;
                    }
                    break;
                case State.expsign:
                    if ( isnum( c ) ) {
                        nExp = parseFloat( c );
                        eS = State.exp;
                    }
                    else if ( c == '-' ) {
                        bNegExp = true;
                        eS = State.exp;
                    }
                    else if ( c != '+' ) {
                        eS = State.end;
                    }
                    break;
                case State.exp:
                    if ( isnum( c ) ) {
                        nExp *= 10;
                        nExp += parseFloat( c );
                        if ( nExp > nMaxExp ) {
                            return false;
                        }
                    }
                    else {
                        eS = State.end;
                    }
                    break;
                case State.end:     // to avoid compiler warning
                    break;      // loop exits anyway
            }

            i++;
        }

        i--;        // set pointer back to last
        rp.pStr = p.substr( i );

        fInt += fFrac;
        var nLog10 = Math.log10( fInt );

        if ( bNegExp ) {
            nExp = -nExp;
        }

        if ( nLog10 + nExp > nMaxExp ) {
            return false;
        }

        fInt = fInt * Math.pow( 10.0, nExp );

        if ( bNegNum ) {
            fInt = -fInt;
        }
{'fraction_non_alphanumeric': 0.13067328675248754, 'fraction_numerical': 0.02722777232777433, 'mean_word_length': 1.0089285714285714, 'pattern_counts': {'":': 1, '<': 47, '<?xml version=': 0, '>': 27, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5557109', 'n_tokens_mistral': 17856, 'n_tokens_neox': 16354, 'n_words': 4049}