在 JavaScript 中将十六进制转换为浮点数

IT技术 javascript numbers hex
2021-02-25 20:59:38

我想将带分数的以 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]);

那么有什么替代方案呢?

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

这个问题让我问了上面的问题。

6个回答

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

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

如果 'parts[0]' 是空字符串,请不要忘记将整数部分默认为 0。例如在解析“.0f”时。请参阅下面凯文的回答。
2021-04-15 20:59:38
谢谢肯特。我宁愿调用 parseFloat 以外的函数。但无论如何它是一个过载:)
2021-04-23 20:59:38

试试这个。

该字符串可以是具有四个字符 (0 - 255) 的原始数据(简单文本)或长度为四个字节的十六进制字符串“0xFFFFFFFF”。

jsfiddle.net

var str = '0x3F160008';

function parseFloat(str) {
    var float = 0, sign, order, mantissa, 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 parameter');
                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;
}
什么变量order没有使用。为什么?
2021-04-30 20:59:38

请试试这个:

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

我结合MarkKent 的答案来制作一个重载的 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);
}

试试这个:

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

反转步骤以转换回来。

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

一个简单的例子:

将十进制23.5转换成十六进制,转换后要小数点后一位。

23.5 x 16 = 376。

转换为十六进制 = 0x178。

以 16 为底的答案:17.8

现在转换回十进制:

取出小数点:0x178

转换为十进制:376

除以 16:23.5