Подтвердить что ты не робот

Javascript float из/в бит

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

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

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

и наоборот -

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

В С# вы можете использовать битконвертер ... floatBits или что-то подобное на Java... Даже в VB6 ради Христа вы можете memcpy float32 в int32. Как я могу перевести между int и float в javascript?

4b9b3361

Ответ 1

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

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

Ответ 2

function DoubleToIEEE(f)
{
    var buf = new ArrayBuffer(8);
    (new Float64Array(buf))[0] = f;
    return [ (new Uint32Array(buf))[0] ,(new Uint32Array(buf))[1] ];
}

Ответ 3

function FloatToIEEE(f)
{
    var buf = new ArrayBuffer(4);
    (new Float32Array(buf))[0] = f;
    return (new Uint32Array(buf))[0];
}

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

Ответ 4

  • JavaScript использует double (IEEE 754) для представления всех номеров
  • double состоит из полей [знака, экспонента (11 бит), мантиссы (52 бит)]. Значение числа вычисляется по формуле (-1)^sign * (1.mantissa) * 2^(exponent - 1023). (1.mantissa - означает, что мы берем биты мантиссы, добавляем 1 в начале и протачиваем это значение как число, например, если mantissa = 101 получаем число 1.101 (bin) = 1 + 1/2 + 1/8 (dec) = 1.625 (dec).
  • Мы можем получить значение тестирования бит sign, если число больше нуля. Существует небольшая проблема с 0 здесь, потому что double имеет значения +0 и -0, но мы можем различать эти два путем вычисления 1/value и проверки значения +Inf или -Inf.
  • Так как 1 <= 1.mantissa < 2 мы можем получить значение экспоненты, используя Math.log2, например. Math.floor(Math.log2(666.0)) = 9, поэтому показатель exponent - 1023 = 9 и exponent = 1032, который в двоичном выражении равен (1032).toString(2) = "10000001000"
  • После того, как мы получим показатель экспоненты, мы можем масштабировать число до нуля без изменения мантиссы, 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).
  • После некоторой строки concat вы получите то, что хотите.

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

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

Ответ 5

Как и другие плакаты, 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/С++ по существу будет использовать Math.floor для преобразования в integer из float.

int для float:

var a = 10;
a.toFixed( 3 ); // result: 10.000