Javascript浮点数与十六进制互相转换 有符号整数与十六进制互相转换 速度超快

32,372 阅读2分钟

查了很多,很少有人写这个的,偶尔找到的代码也有各种问题,要么是特殊情况算错,要么是速度太慢(速度大概是我这个的5%),遂自己写一个,目前应该是全网不要钱的博客里速度最快了吧,如果还有别的优化建议,欢迎交流学习!

前言

简介:(float类型,double类型,integer类型,byte类型)与内存中bit位之间的转换;

基本符合 IEEE754 标准,但不区分 ±0;

经过本人的不断压榨,现在这组函数拥有:

无与伦比的速度,几乎是全网第一;

小巧的体积,简短精美;

依然可能存在bug;

[**]运算符需要 ES7 环境,如果环境不支持需要手动改成 Math.pow();

xxx_to_hex 的参数是 Number,返回的是十六进制 String;

hex_to_xxx 的参数是 Number,返回的是 Number;

tips:hex 在实际使用中会分 MSB或者 LSB,需要特别注意;

以下是代码:

浮点数

单精度与十六进制

float 转 hex

function float_to_hex(float) {
    let S, E, M, HEX;
    if (isNaN(float)) {
        return "7fc00000";
    }
    S = float >= 0 ? 0 : 1;
    E = Math.floor(Math.log((float >= 0 ? float : -float)) / Math.LN2) + 127;
    E = (E >= 0xff) ? 0xff : (E < 0) ? 0 : E;
    M = (E >= 0xff) ? 0 : Math.round((1 << 23) * (Math.sign(float) * float / (2 ** (E - 127 + !E)) - !!E));
    HEX = (((S << 31) | (E << 23) | M) >>> 0).toString(16);
    while (HEX.length < 8) {
        HEX = "0" + HEX;
    }
    return HEX;
}

hex 转 float

function hex_to_float(hex) {
    let S, E, M, result;
    S = hex >>> 31;
    E = ((hex << 1) >>> 24);
    M = (hex << 9) >>> 9;
    if (E === 0xff) {
        if (M === 0x0) {
            return ((-1) ** S) * Infinity;
        } else {
            return NaN;
        }
    }
    result = ((-1) ** S) * (M / (1 << 23) + !!(E)) * (2 ** (E - 127 + !E));
    return result;
}

双精度与十六进制

double 转 hex

function double_to_hex(double) {
    let S, E, M, HEX, HEX1, HEX2;
    if (isNaN(double)) {
        return "7ff8000000000000";
    }
    S = double >= 0 ? 0 : 1;
    E = Math.floor(Math.log(double >= 0 ? double : -double) / Math.LN2) + 1023;
    E = (E >= 0x7ff) ? 0x7ff : (E < 0) ? 0 : E;
    M = (E >= 0x7ff) ? 0 : Math.round((2 ** 52) * (Math.sign(double) * double / (2 ** (E - 1023 + !E)) - !!E));
    HEX1 = ((S << 11) | E).toString(16);
    HEX2 = M.toString(16);
    while (HEX2.length < 13) {
        HEX2 = "0" + HEX2;
    }
    HEX = HEX1 + HEX2;
    while (HEX.length < 16) {
        HEX = "0" + HEX;
    }
    return HEX;
}

hex 转 double

function hex_to_double(hex) {
    let hex1, hexstr, S, E, M, result;
    hex1 = parseInt(hex / (2 ** 32));
    hexstr = String(hex.toString(16));
    while (hexstr.length < 16) {
        hexstr = "0" + hexstr;
    }
    S = hex1 >>> 31;
    E = ((hex1 << 1) >>> 21);
    M = parseInt(hexstr.substring(3), 16) / (2 ** 52) + !!E;
    if (E === 0x7ff) {
        if (M === 0x0) {
            return ((-1) ** S) * Infinity;
        } else {
            return NaN;
        }
    }
    result = ((-1) ** S) * M * (2 ** (E - 1023 + !E));
    return result;
}

整数

32位整数与十六进制

integer 转 hex

function integer_to_hex(int) {
    let S, V, HEX;
    S = (int >>> 31) << 30;
    V = (int << 1) >>> 1;
    HEX = (S + S + V).toString(16);
    while (HEX.length < 8) {
        HEX = "0" + HEX;
    }
    return HEX;
}

hex 转 integer

function hex_to_integer(hex) {
    return hex >> 0;
}

8位整数与十六进制

byte 转 hex:

function byte_to_hex(byte) {
    let HEX;
    HEX = (byte & 0xff).toString(16)
    return HEX.length == 1 ? "0" + HEX : HEX;
}

hex 转 byte:

function hex_to_byte(hex) {
    return (hex << 24) >> 24;
}

才疏学浅,如有错误,恳请指正!