在javascript中将十六进制转换为float

时间:2011-02-20 07:01:42

标签: javascript numbers hex

This question让我问下面的问题。

我想将基数为10的数字转换为基数为16的数字。

var myno = 28.5;

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

一切都很顺利。现在我想将它转换回十进制 但现在我不能写

var orgno = parseInt( convno, 16 );
alert( orgno );

因为它不返回小数部分。

并且不能使用parseFloat,因为根据MDC,parseFloat的语法是

parseFloat(str);

如果我必须转换回int,那就不会有问题,因为parseInt语法是

parseInt(str [, radix]);

那么替代方案是什么呢?

免责声明:我认为这是一个微不足道的问题,但谷歌搜索没有给我答案。

7 个答案:

答案 0 :(得分:12)

另一种可能性是分别解析数字,将字符串分成两部分,并在转换过程中将两个部分视为整数,然后将它们重新组合在一起。

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);
alert(myno + " -> " + convno + " -> " + f );

答案 1 :(得分:4)

我结合了Mark和Kent的答案来制作一个重载的parseFloat函数,该函数接受基数的参数(更简单,更通用):

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);
}

我希望这有助于某人!

答案 2 :(得分:4)

试试这个。

字符串可以是带有4个字符(0 - 255)或的字符的原始数据(简单文本) 十六进制字符串“0xffffffff”4字节长度

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;
}

答案 3 :(得分:2)

试试这个:

  1. 确定小数点后所需的精度位数。
  2. 将您的原始数字乘以16的幂(例如,如果您想要两位数,则为256)。
  3. 将其转换为整数。
  4. 根据您在步骤1中的决定手动设置小数点。
  5. 撤消转换回来的步骤。

    1. 取出小数点,记住它的位置。
    2. 以整数形式将十六进制转换为十进制。
    3. 将结果除以16的适当幂(16 ^ n,其中n是您在步骤1中取出的小数点后的位数)。
    4. 一个简单的例子:

      将十进制23.5转换为十六进制,并希望转换后的小数点后一位数。

      23.5 x 16 = 376。

      转换为十六进制= 0x178。

      答案基础16:17.8

      现在转换回十进制:

      取出小数点:0x178

      转换为十进制:376

      除以16:23.5

答案 4 :(得分:2)

请试试这个:

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];
}

答案 5 :(得分:1)

这是Mark Eirich's answer的尺寸改进:

function hex2dec(hex) {
  let h = hex.split(/\./);
  return ('0x'+h[1])*(16**-h[1].length)+ +('0x'+h[0]);
}

function hex2dec(hex) {
  let h = hex.split(/\./);
  return ('0x'+h[1])*(16**-h[1].length)+ +('0x'+h[0]);
}

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>

答案 6 :(得分:0)

我不确定你想在那里解析什么十六进制格式,是这样的:“a1.2c”?

浮点数通常使用IEEE 754 standard以十六进制格式存储。该标准不使用任何点(纯十六进制字母不存在)。而不是有3组预定义长度的位(1 + 8 + 23 =总共32位──双倍使用64位)。

我编写了以下函数来将这样的数字解析为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);
}