5

I would like to render a JavaScript bigint value to a string in scientific notation.

I thought of Number.toExponential() but it only works for numbers.

const scientificNotation = n => parseInt(n).toExponential();

console.log(scientificNotation(prompt()));

0

1 Answer 1

5

Intl does support Bigint:

Turns out BigInt.prototype.toLocaleString() can be used with an options for scientific-notation:

const fmt /*: BigIntToLocaleStringOptions */ = {
  notation: 'scientific',
  maximumFractionDigits: 20 // The default is 3, but 20 is the maximum supported by JS according to MDN.
};

const b1 = 1234567890123456789n;

console.log( b1.toLocaleString( 'en-US', fmt ) ); // "1.234567890123456789E18" 

Original answer:

(This code is still useful for JS environments without Intl support or if you need more than 20 digits of precision):

Because bigint values are always integral, and because bigint.toString() will return base-10 digits without further ceremony (other than a leading - for negative values) then then a quick-and-dirty method is to take those rendered digits and insert a radix point (aka decimal dot) after the first digit and tack on the exponent at the end, and because it's a base-10 string the exponent is the same as the length of the rendered string (neat, huh?)

function bigIntToExponential( value: bigint ): string {
    
    if( typeof value !== 'bigint' ) throw new Error( "Argument must be a bigint, but a " + ( typeof value ) + " was supplied." );

    //

    const isNegative = value < 0;
    if( isNegative ) value = -value; // Using the absolute value for the digits.

    const str = value.toString();
    
    const exp = str.length - 1;
    if( exp == 0 ) return ( isNegative ? "-" : '' ) + str + "e+0";

    const mantissaDigits = str.replace( /(0+)$/, '' ); // Remove any mathematically insignificant zeroes.

    // Use the single first digit for the integral part of the mantissa, and all following digits for the fractional part (if any).
    let mantissa = mantissaDigits.charAt( 0 );
    if( mantissaDigits.length > 1 ) {
        mantissa += '.' + mantissaDigits.substring( 1 );
    }

    return ( isNegative ? "-" : '' ) + mantissa + "e+" + exp.toString();
}

console.log( bigIntToExponential( 1n ) );    // "1e+0"
console.log( bigIntToExponential( 10n ) );   // "1e+1"
console.log( bigIntToExponential( 100n ) );  // "1e+2"
console.log( bigIntToExponential( 1000n ) ); // "1e+3"
console.log( bigIntToExponential( 10000n ) ); // "1e+4" 
console.log( bigIntToExponential( 1003n ) ); // "1.003e+3" 
console.log( bigIntToExponential( 10000000003000000n) ); // "1.0000000003e+16" 
console.log( bigIntToExponential( 1234567890123456789n ) ); // "1.234567890123456789e+18" 
console.log( bigIntToExponential( 12345678901234567898765432109876543210n ) ); // "1.234567890123456789876543210987654321e+37" 

console.log( bigIntToExponential( -1n ) );    // "-1e+0"
console.log( bigIntToExponential( -10n ) );   // "-1e+1"
console.log( bigIntToExponential( -100n ) );  // "-1e+2"
console.log( bigIntToExponential( -1000n ) ); // "-1e+3"
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.