admin管理员组

文章数量:1026180

My understanding is that all numbers in JavaScript are double-precision floating-point. How can I convert a double to a float in JavaScript? I understand the precision loss, but that is tolerable.

I need to depict C style floating point numbers

My understanding is that all numbers in JavaScript are double-precision floating-point. How can I convert a double to a float in JavaScript? I understand the precision loss, but that is tolerable.

I need to depict C style floating point numbers

Share Improve this question edited Aug 4, 2016 at 21:51 marc asked Aug 4, 2016 at 21:32 marcmarc 8271 gold badge12 silver badges29 bronze badges 5
  • 1 One way would be to use new Float32Array([yourNumber])[0], but it’s not supported in all browsers. Why do you need the lost precision? – Sebastian Simon Commented Aug 4, 2016 at 21:34
  • 2 What do you need a "float" for? Context will help us understand what you are going for – qxz Commented Aug 4, 2016 at 21:40
  • I need to depict c style floating point numbers – marc Commented Aug 4, 2016 at 21:41
  • For what? JS doesn't have C-style floats. Are you interfacing with C code? – qxz Commented Aug 4, 2016 at 21:44
  • What function/library are you trying to call, and using what means? REST API? – qxz Commented Aug 4, 2016 at 22:24
Add a ment  | 

3 Answers 3

Reset to default 5

This will work in modern engines:

function doubleToFloat ( d ) {
    if ( Float32Array )
        return new Float32Array([d])[0];
}

Note that the data type of the result is still number (double precision), but it only uses 32 bits of information. I added a fallback for the case that Float32Array is not available:

function doubleToFloat ( d ) {
    if ( Float32Array )
        return new Float32Array( [ d ] )[ 0 ];

    if ( d === 0 )
        return d;

    var sign = 2*(d >= 0) - 1;
    var b = Math.abs( d ).toString( 2 );
    var decimalIndex = b.indexOf( '.' );
    var oneIndex = b.indexOf( '1' );
    var exponent, mantissa, round, result;

    if( decimalIndex === -1 ) {
        exponent = b.length - 1;
        mantissa = b.substr( 1, 23 );
        round = +( mantissa.length === 23 && b[24] === '1' );
        result = sign*( parseInt( '1' + mantissa, 2 ) + round )*Math.pow( 2, exponent - mantissa.length );
    } else if ( decimalIndex === 1 ) {
        exponent = 1 - oneIndex;       
        if ( oneIndex === 0 ) {
            mantissa = '1' + b.substr( 2, 23 );
            round = +( mantissa.length === 24 && b[25] === '1' );
            result = sign*( parseInt( mantissa, 2 ) + round )*Math.pow( 2, 1 - mantissa.length );
        } else {
            mantissa = b.substr( oneIndex, 24 );
            round = +( mantissa.length === 24 && b[oneIndex + 24] === '1' );
            result = sign*( parseInt( mantissa, 2 ) + round )*Math.pow( 2, 1 + exponent - mantissa.length );
        }
    } else {
        exponent = decimalIndex - 1;
        mantissa = b.replace( '.', '' ).substr( 1, 23 );
        round = +( mantissa.length === 23 && b.replace( '.', '' )[24] === '1' );
        result = sign*( parseInt( '1' + mantissa, 2 ) + round )*Math.pow( 2, decimalIndex - mantissa.length - 1 );
    }

    if ( exponent < -126 )
        return 0;
    if ( exponent > 127 )
        return sign*Infinity;

    return result;
}

Another way is:

var doubleValue = Math.random()
var floatValue = ((doubleValue * 1e7) | 0) / 1e7

Just use Math.fround() - it returns the nearest 32-bit single precision float representation of a number.

Math.fround() - JavaScript | MDN

My understanding is that all numbers in JavaScript are double-precision floating-point. How can I convert a double to a float in JavaScript? I understand the precision loss, but that is tolerable.

I need to depict C style floating point numbers

My understanding is that all numbers in JavaScript are double-precision floating-point. How can I convert a double to a float in JavaScript? I understand the precision loss, but that is tolerable.

I need to depict C style floating point numbers

Share Improve this question edited Aug 4, 2016 at 21:51 marc asked Aug 4, 2016 at 21:32 marcmarc 8271 gold badge12 silver badges29 bronze badges 5
  • 1 One way would be to use new Float32Array([yourNumber])[0], but it’s not supported in all browsers. Why do you need the lost precision? – Sebastian Simon Commented Aug 4, 2016 at 21:34
  • 2 What do you need a "float" for? Context will help us understand what you are going for – qxz Commented Aug 4, 2016 at 21:40
  • I need to depict c style floating point numbers – marc Commented Aug 4, 2016 at 21:41
  • For what? JS doesn't have C-style floats. Are you interfacing with C code? – qxz Commented Aug 4, 2016 at 21:44
  • What function/library are you trying to call, and using what means? REST API? – qxz Commented Aug 4, 2016 at 22:24
Add a ment  | 

3 Answers 3

Reset to default 5

This will work in modern engines:

function doubleToFloat ( d ) {
    if ( Float32Array )
        return new Float32Array([d])[0];
}

Note that the data type of the result is still number (double precision), but it only uses 32 bits of information. I added a fallback for the case that Float32Array is not available:

function doubleToFloat ( d ) {
    if ( Float32Array )
        return new Float32Array( [ d ] )[ 0 ];

    if ( d === 0 )
        return d;

    var sign = 2*(d >= 0) - 1;
    var b = Math.abs( d ).toString( 2 );
    var decimalIndex = b.indexOf( '.' );
    var oneIndex = b.indexOf( '1' );
    var exponent, mantissa, round, result;

    if( decimalIndex === -1 ) {
        exponent = b.length - 1;
        mantissa = b.substr( 1, 23 );
        round = +( mantissa.length === 23 && b[24] === '1' );
        result = sign*( parseInt( '1' + mantissa, 2 ) + round )*Math.pow( 2, exponent - mantissa.length );
    } else if ( decimalIndex === 1 ) {
        exponent = 1 - oneIndex;       
        if ( oneIndex === 0 ) {
            mantissa = '1' + b.substr( 2, 23 );
            round = +( mantissa.length === 24 && b[25] === '1' );
            result = sign*( parseInt( mantissa, 2 ) + round )*Math.pow( 2, 1 - mantissa.length );
        } else {
            mantissa = b.substr( oneIndex, 24 );
            round = +( mantissa.length === 24 && b[oneIndex + 24] === '1' );
            result = sign*( parseInt( mantissa, 2 ) + round )*Math.pow( 2, 1 + exponent - mantissa.length );
        }
    } else {
        exponent = decimalIndex - 1;
        mantissa = b.replace( '.', '' ).substr( 1, 23 );
        round = +( mantissa.length === 23 && b.replace( '.', '' )[24] === '1' );
        result = sign*( parseInt( '1' + mantissa, 2 ) + round )*Math.pow( 2, decimalIndex - mantissa.length - 1 );
    }

    if ( exponent < -126 )
        return 0;
    if ( exponent > 127 )
        return sign*Infinity;

    return result;
}

Another way is:

var doubleValue = Math.random()
var floatValue = ((doubleValue * 1e7) | 0) / 1e7

Just use Math.fround() - it returns the nearest 32-bit single precision float representation of a number.

Math.fround() - JavaScript | MDN

本文标签: floating pointFrom double to float in JavaScriptStack Overflow