JavaScript упаковывает целые числа и вычисляет произвольную точность с плавающей точкой: - PullRequest
2 голосов
/ 20 июля 2011

Мне нужно сделать следующее в JavaScript, и до сих пор не удалось найти решения, чтобы сделать это без проблем:

  • Возьмите два целых числа в определенном порядке и упакуйте их, как модуль Python для структуры.
  • Это упакованное значение (бонус за поддержку порядка байтов, отличного от хоста) будет преобразовано в 64-битное число с плавающей запятой (double).Они должны быть произвольными, поэтому я мог бы получить экспоненциальное представление целого числа (скажем, они могли бы быть 0xdeadbeef и 500):

    В форме exp: 1.0883076389305e-311 1.0883076389305000 * 10 ^ - 311

  • Мне нужно, чтобы преобразовать его в произвольной точности, формы, не показатель, так:

    0,0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000108830763893050000000000000000000000000000000000000000000000000000000000000000000000000000

Я не нашел способа сделать это в Javascript, и мне нужно вывести некоторые числа, подобные той, которая должна поддерживать произвольную точность или, по крайней мере, масштаба до1024 показателя (или, скажем, 400) удвоенияes.

Спасибо !!

Примечание: мне нужно, чтобы "упаковка / распаковка" была точным представлением этих двух чисел, преобразованных в двойное / 64-битное число с плавающей точкой.Но меня не волнует, скажем, экспорт в строковый или необработанный буфер.Пока я получаю двойное представление произвольной точности для double, все в порядке.

Ответы [ 2 ]

4 голосов
/ 20 июля 2011

1: Khronos имеет текущую спецификацию для интерфейса DataView как часть требований WebGL TypedArray, которые в сочетании с Int32Array и Float64Array позволят вам записать ваши два целых числа в буфер и считать их обратно как двойные.

К сожалению, поддержка браузера для этого не существуетПока что не часто - чтобы проверить ваш браузер, посетите http://html5test.com/ и посмотрите раздел, озаглавленный «Собственные двоичные данные».

Без поддержки TypedArray выше я неЯ думаю, что есть какой-то способ сделать это с помощью бит-тиддлинга, так как битовые операторы Javascript обрабатывают числа как 32-битные беззнаковые значения, поэтому у вас не будет доступа к битам старшего разряда.У меня нет никакой конкретной формы, IEE754 - это просто внутреннее представление.

3: это точка, в которой вы можете попытаться показать фактическую точность.К сожалению, встроенный метод, например Number.toFixed(), не поддерживает отображение более 20 знаков после запятой.Вам нужно будет проанализировать экспоненциальную форму и вручную построить строку с соответствующим количеством ведущих нулей.

NB - диапазон экспонент двойного числа равен 2 ^ 1024, а не 10 ^ 1024, поэтому реальный предел равенна самом деле ~ 1,0E ± 308 - ваш примерный показатель меньше этого диапазона.

EDIT на самом деле, может быть способ, но я не могу гарантировать точность этого:

  1. возьмите два целых числа, назовите их hi и lo.
  2. извлеките показатель степени - exp = (hi >> 20) & 0x7ff
  3. извлеките знак - sign = (hi >> 31)
  4. Извлечь мантиссу - ((hi & 0xfffff) * Math.pow(2, 32) + lo) / Math.pow(2, 52)
  5. result = (1 + m) * (Math.pow(2.0, exp - 1023))
  6. if (sign) result *= -1

РЕДАКТИРОВАТЬ 2 - это работает!См. http://jsfiddle.net/alnitak/assXS/

var hex2double = function(input) {

    var hi = parseInt(input.substring(0, 8), 16);
    var lo = parseInt(input.substring(8   ), 16);

    var p32 = 0x100000000;
    var p52 = 0x10000000000000;

    var exp = (hi >> 20) & 0x7ff;
    var sign = (hi >> 31);
    var m = 1 + ((hi & 0xfffff) * p32 + lo) / p52;
    m = exp ? (m + 1) : (m * 2.0);

    return (sign ? -1 : 1) * m * Math.pow(2, exp - 1023);
};

Введите число с плавающей запятой в http://babbage.cs.qc.edu/IEEE-754/Decimal.html,, возьмите полученную шестнадцатеричную строку из нижнего ряда выходных данных и передайте ее функции выше.Вы должны увидеть предупреждение, содержащее исходное значение.

EDIT 3 код исправлен для учета особого случая, когда все биты экспоненты равны нулю.

0 голосов
/ 20 июля 2011

Я думаю, вам нужна библиотека больших чисел для JavaScript, такая как http://jsfromhell.com/classes/bignumber.

...