JavaScript плавать из / в биты - PullRequest
21 голосов
/ 05 января 2010

Я пытаюсь выполнить что-то простое на любом другом языке, кроме javascript: вытащить биты из плавающего (и наоборот)

В C / C ++ это будет что-то вроде

float a = 3.1415;
int b = *((int*)&a);

и наоборот

int a = 1000;
float b = *((float*)&a);

В C # вы можете использовать BitConverter ... floatBits или что-то похожее в Java ... Даже в VB6, ради бога, вы можете записать float32 в int32. Как же я могу переводить между и INT и плавать в JavaScript?

Ответы [ 5 ]

20 голосов
/ 17 января 2013
function DoubleToIEEE(f)
{
    var buf = new ArrayBuffer(8);
    (new Float64Array(buf))[0] = f;
    return [ (new Uint32Array(buf))[0] ,(new Uint32Array(buf))[1] ];
}
10 голосов
/ 05 января 2010

Вы, конечно, не получаете ничего такого низкого уровня в JavaScript. Было бы крайне опасно разрешать перерисовку и изменение указателя на языке, который должен быть безопасным для использования ненадежными потенциальными злоумышленниками веб-сайтами.

Если вы хотите получить 32-разрядное представление IEEE754 значения одинарной точности в Number (которое помните, что также не является целым; единственный тип чисел, который вы получаете в JavaScript - это double), вам придется сделайте это сами, поиграв вместе биты знака, экспоненты и мантиссы. Вот пример кода здесь .

2 голосов
/ 25 сентября 2012
function FloatToIEEE(f)
{
    var buf = new ArrayBuffer(4);
    (new Float32Array(buf))[0] = f;
    return (new Uint32Array(buf))[0];
}

К сожалению, это не работает с парными и старыми браузерами.

0 голосов
/ 26 июля 2015
  1. JavaScript использует double (IEEE 754) для представления всех чисел
  2. double состоит из полей [знак, экспонента (11 бит), мантисса (52 бит)]. Значение числа вычисляется по формуле (-1)^sign * (1.mantissa) * 2^(exponent - 1023). (1.mantissa - означает, что мы берем биты мантиссы с добавлением 1 в начале и переводим это значение в число, например, если мантисса = 101, мы получаем число 1.101 (bin) = 1 + 1/2 + 1/8 (dec) = 1.625 (dec).
  3. Мы можем получить значение sign битовое тестирование, если число больше нуля. Здесь есть небольшая проблема с 0, потому что double имеют значения +0 и -0, но мы можем различить эти два, вычислив 1/value и проверив, является ли значение +Inf или -Inf.
  4. Поскольку 1 <= 1.mantissa < 2, мы можем получить значение показателя степени, используя Math.log2, например. Math.floor(Math.log2(666.0)) = 9 так что показатель степени равен exponent - 1023 = 9 и exponent = 1032, что в двоичном виде равно (1032).toString(2) = "10000001000"
  5. После того как мы получим показатель степени, мы можем масштабировать число до нулевого показателя без изменения мантиссы, value = value / Math.pow(2, Math.floor(Math.log2(666.0))), теперь значение представляет число (-1)^sign * (1.mantissa). Если мы проигнорируем знак и умножим это на 2^52, мы получим целочисленное значение, которое имеет те же биты, что и 1.mantissa: ((666 / Math.pow(2, Math.floor(Math.log2(666)))) * Math.pow(2, 52)).toString(2) = "10100110100000000000000000000000000000000000000000000" (мы должны игнорировать ведущий 1).
  6. После некоторой строки concat вы получите то, что хотите

Это только подтверждение концепции, мы не обсуждали денормализованные числа или специальные значения, такие как NaN - но я думаю, что это можно расширить, чтобы учесть и эти случаи.

@ bensiu отвечает хорошо, но если вы используете какой-то старый интерпретатор JS, вы можете использовать этот подход.

0 голосов
/ 05 января 2010

Как говорили другие авторы, JavaScript типизирован свободно, поэтому нет различий в типах данных от float до int или наоборот.

Однако, то, что вы ищете, это

float to int:

Math.floor( 3.9 ); // result: 3 (truncate everything past .) or
Math.round( 3.9 ); // result: 4 (round to nearest whole number)

В зависимости от того, что вы хотите. В C / C ++ он по существу будет использовать Math.floor для преобразования в целое число из числа с плавающей точкой.

int to float:

var a = 10;
a.toFixed( 3 ); // result: 10.000
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...