Search code examples
javascriptieee-754

How to Get Decimal from Sign, Mantissa, and Exponent in Javascript


I am trying to get the ieee754 32-bit representation of a decimal/float. I am using this code to get the mantissa, sign, and exponent:

function decodeIEEE64 ( value ) {

  if ( typeof value !== "number" )
    throw new TypeError( "value must be a Number" );

  var result = {
    isNegative : false,
    exponent : 0,
    mantissa : 0
  };

  if ( value === 0 ) {
    return result;
  }

  // not finite?
  if ( !isFinite( value ) ) {
    result.exponent = 2047;
    if ( isNaN( value ) ) {
      result.isNegative = false;
      result.mantissa = 2251799813685248; // QNan
    } else {
      result.isNegative = value === -Infinity;
      result.mantissa = 0;
    }
    return result;
  }

  // negative?
  if ( value < 0 ) {  result.isNegative = true;  value = -value;  }

  // calculate biased exponent
  var e = 0;
  if ( value >= Math.pow( 2, -1022 ) ) { // not denormalized
    // calculate integer part of binary logarithm
    // http://en.wikipedia.org/wiki/Binary_logarithm
    var r = value;
    while ( r < 1 ) { e -= 1; r *= 2; }
    while ( r >= 2 ) { e += 1; r /= 2; }
    e += 1023; // add bias
  }
  result.exponent = e;

  // calculate mantissa
  if ( e != 0 ) {
    var f = value / Math.pow( 2, e - 1023 );
    result.mantissa = Math.floor( (f - 1) * Math.pow( 2, 52 ) );
  } else { // denormalized
    result.mantissa = Math.floor( value / Math.pow( 2, -1074 ) );
  }

  return result;
}

var results = decodeIEEE64(0.07);
console.log(results);

The example I am trying to work with is 0.07. I should be able to get the 32-bit ieee754 as 0.070000000298...

For 0.07 my code gives me {isNegative: false, exponent: 1019, mantissa: 540431955284460} I believe I should format it as sign 2^exponent mantissa

If I do sign 2^exponent mantissa I get: 0-5.61779105e306-540431955284460 which leads me to believe that I should convert to binary first. To do that, I have tried using this code:

function toBinary (decimal) {
    return decimal.toString(2);
}

So I do toBinary(Math.pow(2, exponent)) and toBinary(mantissa) and now get 0-100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000-1111010111000010100011110101110000101000111101100 which makes me feel like I'm doing something wrong

Based on http://www.binaryconvert.com/result_float.html?decimal=048046048055 I should get 0-01111011-00011110101110000101001 but I don't know where I would go from there, binary to decimal without the dashes?

If anyone can help me, it will be much appreciated! Thanks!


Solution

  • function convert(){
        var num = parseFloat($("#inp").val(),10);
        
        var str = num.toString(2); // binary representation
    console.log(num);
        //Normalize and find the exponent and mantissa
        var mantissa = parseInt(str.substring(0,str.indexOf(".")));
        var exp = 0;
       console.log(mantissa);
        if(mantissa <=0){
           var i = str.indexOf(".") +1;
           while(parseInt(str.charAt(i),10) < 1){
            i = i +1;
           } 
           exp = 127 - (i -1); //bias as 127;
           mantissa = str.substring(i+1);
        }
        
         else if(mantissa > 0){
           var i = str.indexOf(".");
           exp = i -1;        
           exp = 127 +exp; //bias as 127;
           mantissa = str.replace(".","").substring(1);
        }
       
        return "0 " + exp.toString(2).padStart(8,"0") + " "+mantissa;
        }
        
        $(document).ready(function(){
         // $("#result").text(convert());
          $("#inp").change(function(){
            $("#result").text(convert());
          });
        });
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <input id ="inp"></input>
    <div id ="result"></div>