Преобразование шестнадцатеричного в плавающий в JavaScript - PullRequest
19 голосов
/ 20 февраля 2011

Этот вопрос заставил меня задать следующий вопрос.

Я хотел бы преобразовать число в базе 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]);

Так что же является альтернативой?за это?

Отказ от ответственности: я думал, что это тривиальный вопрос, но поиск в Google не дал мне ответов.

Ответы [ 6 ]

12 голосов
/ 20 февраля 2011

Другая возможность состоит в том, чтобы разбирать цифры по отдельности, разбивая строку на две части и обрабатывая обе части как целые во время преобразования, а затем складывать их вместе.

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

4 голосов
/ 30 декабря 2012

Попробуйте это.

строка может быть необработанными данными (простой текст) с 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;
}
4 голосов
/ 21 января 2012

Я объединил ответы Марка и Кента, чтобы создать перегруженную функцию parseFloat, которая принимает аргумент для radix (намного проще и более универсальным):

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 голосов
/ 20 февраля 2011

Пожалуйста, попробуйте это:

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];
}
2 голосов
/ 20 февраля 2011

Попробуйте это:

  1. Определите, сколько цифр точности вам нужно после десятичной точки.
  2. Умножьте ваш исходный номер на 16 (например, 256, если вам нужны две цифры).
  3. Преобразовать его в целое число.
  4. Введите десятичную точку вручную в соответствии с тем, что вы решили на шаге 1.

Повторите шаги для обратного преобразования.

  1. Уберите десятичную точку, вспомнив, где она была.
  2. Преобразование шестнадцатеричного числа в десятичное в целочисленном виде.
  3. Разделите результат на соответствующую степень 16 (16 ^ n, где n - количество цифр после десятичной точки, которое вы вывели на шаге 1).

Простой пример:

Преобразовать десятичное число 23,5 в шестнадцатеричное и получить одну цифру после десятичной точки после преобразования.

23,5 х 16 = 376

Преобразовано в гекс = 0x178.

Ответ в базе 16: 17,8

Теперь переведите обратно в десятичное число:

Удалить десятичную точку: 0x178

Преобразование в десятичное число: 376

Разделить на 16: 23,5

0 голосов
/ 11 апреля 2012

Я не уверен, какой шестнадцатеричный формат вы хотели там проанализировать, это было что-то вроде: "a1.2c"?

Число с плавающей запятой обычно хранится в шестнадцатеричном формате с использованием стандарта IEEE 754 . Этот стандарт не использует никаких точек (которые не существуют в чистом шестнадцатеричном алфавите). Вместо этого есть 3 группы битов заданной длины (всего 1 + 8 + 23 = 32 бита - двойное использование 64 бита).

Я написал следующую функцию для разбора таких чисел в число с плавающей точкой:

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