Converting hexadecimal to float in JavaScript

前端 未结 7 1485
抹茶落季
抹茶落季 2020-11-28 14:14

I would like to convert a number in base 10 with fraction to a number in base 16.

var myno = 28.5;

var convno = myno.toString(16);
alert(convno);


        
相关标签:
7条回答
  • 2020-11-28 14:43

    Try this:

    1. Decide how many digits of precision you need after the decimal point.
    2. Multiply your original number by that power of 16 (e.g. 256 if you want two digits).
    3. Convert it as an integer.
    4. Put the decimal point in manually according to what you decided in step 1.

    Reverse the steps to convert back.

    1. Take out the decimal point, remembering where it was.
    2. Convert the hex to decimal in integer form.
    3. Divide the result by the the appropriate power of 16 (16^n, where n is the number of digits after the decimal point you took out in step 1).

    A simple example:

    Convert decimal 23.5 into hex, and want one digit after the decimal point after conversion.

    23.5 x 16 = 376.

    Converted to hex = 0x178.

    Answer in base 16: 17.8

    Now convert back to decimal:

    Take out the decimal point: 0x178

    Convert to decimal: 376

    Divide by 16: 23.5

    0 讨论(0)
  • 2020-11-28 14:45

    I'm not sure what hexadecimal format you wanted to parse there, was this something like: "a1.2c"?

    Floats are commonly stored in hexadecimal format using IEEE 754 standard. That standard doesn't use any dots (which don't exist in pure hexadecimal alphabet). Instead of that there are 3 groups of bits of predefined length (1 + 8 + 23 = 32bits in total ─ double uses 64bits).

    I've written the following function for parsing such a numbers into float:

    function hex2float(num) {
        var sign = (num & 0x80000000) ? -1 : 1;
        var exponent = ((num >> 23) & 0xff) - 127;
        var mantissa = 1 + ((num & 0x7fffff) / 0x7fffff);
        return sign * mantissa * Math.pow(2, exponent);
    }
    
    0 讨论(0)
  • 2020-11-28 14:49

    I combined Mark's and Kent's answers to make an overloaded parseFloat function that takes an argument for the radix (much simpler and more versatile):

    function parseFloat(string, radix)
    {
        // Split the string at the decimal point
        string = string.split(/\./);
        
        // If there is nothing before the decimal point, make it 0
        if (string[0] == '') {
            string[0] = "0";
        }
        
        // If there was a decimal point & something after it
        if (string.length > 1 && string[1] != '') {
            var fractionLength = string[1].length;
            string[1] = parseInt(string[1], radix);
            string[1] *= Math.pow(radix, -fractionLength);
            return parseInt(string[0], radix) + string[1];
        }
        
        // If there wasn't a decimal point or there was but nothing was after it
        return parseInt(string[0], radix);
    }
    
    0 讨论(0)
  • 2020-11-28 14:55

    Another possibility is to parse the digits separately, splitting the string up in two and treating both parts as ints during the conversion and then add them back together.

    function parseFloat(str, radix)
    {
            var parts = str.split(".");
            if ( parts.length > 1 )
            {
                    return parseInt(parts[0], radix) + parseInt(parts[1], radix) / Math.pow(radix, parts[1].length);
            }
            return parseInt(parts[0], radix);
    }
    
    var myno = 28.4382;
    var convno = myno.toString(16);
    var f = parseFloat(convno, 16);
    console.log(myno + " -> " + convno + " -> " + f );

    0 讨论(0)
  • 2020-11-28 14:57

    Try this.

    string may be raw data(simple text) with 4 chars(0 - 255) or hex string "0xffffffff" 4 bytes length

    jsfiddle.net

    var str = '0x3F160008';
    
    function parseFloat(str) {
        var float = 0, sign, order, mantiss,exp,
        int = 0, multi = 1;
        if (/^0x/.exec(str)) {
            int = parseInt(str,16);
        }else{
            for (var i = str.length -1; i >=0; i -= 1) {
                if (str.charCodeAt(i)>255) {
                    console.log('Wrong string parametr'); 
                    return false;
                }
                int += str.charCodeAt(i) * multi;
                multi *= 256;
            }
        }
        sign = (int>>>31)?-1:1;
        exp = (int >>> 23 & 0xff) - 127;
        mantissa = ((int & 0x7fffff) + 0x800000).toString(2);
        for (i=0; i<mantissa.length; i+=1){
            float += parseInt(mantissa[i])? Math.pow(2,exp):0;
            exp--;
        }
        return float*sign;
    }
    
    0 讨论(0)
  • 2020-11-28 15:00

    Please try this:

    function hex2dec(hex) {
        hex = hex.split(/\./);
        var len = hex[1].length;
        hex[1] = parseInt(hex[1], 16);
        hex[1] *= Math.pow(16, -len);
        return parseInt(hex[0], 16) + hex[1];
    }
    

    function hex2dec(hex) {
      hex = hex.split(/\./);
      var len = hex[1].length;
      hex[1] = parseInt(hex[1], 16);
      hex[1] *= Math.pow(16, -len);
      return parseInt(hex[0], 16) + hex[1];
    }
    
    
    
    // ----------
    // TEST
    // ----------
    
    function calc(hex) {
      let dec = hex2dec(hex);
      msg.innerHTML = `dec: <b>${dec}</b><br>hex test: <b>${dec.toString(16)}</b>`
    } 
    
    let init="bad.a55";
    inp.value=init;
    calc(init);
    <input oninput="calc(this.value)" id="inp" /><div id="msg"></div>

    0 讨论(0)
提交回复
热议问题