Таинственный 2, возникающий при выводе моего JavaScript десятичного в двоичный преобразователь? - PullRequest
2 голосов
/ 06 марта 2012

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

function dectobin(d) {
            if (0 >= d) { return 0; }
            else if (1 == d) { return 1; }
            else {
                return 10 * dectobin(Math.floor(d / 2)) + (d % 2);
            }
        }

Теперь проблема в том, что когда я тестирую его с 70007, кажется, что некоторое переполнение 1в последней рекурсии, когда последняя запись попадает из стека.Таким образом, как только dectobin (35003) возвращается с 100010001011101, он масштабируется от 10 до 1000100010111010, и предполагается, что 1 будет добавлен.За исключением того, что вместо 1, он добавляет 2, поэтому получается ответ: 1000100010111012. Теперь я проверил свою логику и математику и не нашел в этом никакой ошибки, поэтому у меня есть ощущение, что это внутренняя структура языка, которая вызывает это.ошибка.Так что, если кто-нибудь может помочь мне здесь и объяснить мне, в чём проблема, которая будет наиболее приятной.Заранее спасибо.

Ответы [ 3 ]

2 голосов
/ 06 марта 2012

Для записи: вы можете преобразовать десятичную в двоичную (строковую), используя:

(70007).toString(2)

Нет необходимости умножать на 10. Более того 0 >= d никогда не будет выполнено.

Переписав вашу функцию:

function dectobin(d) {
  function recurse(dd) {
    return dd > 1 ? recurse(Math.floor(dd/2))+''+dd%2 : dd;
  }
  return recurse(d);
}

Должен дать правильный результат

1 голос
/ 06 марта 2012

Числа длиной более 15 цифр не являются надежными в JavaScript из-за внутреннего представления чисел при удвоении IEEE.

Например,

10001000101110110+1 == 10001000101110112
10001000101110110+2 == 10001000101110112
10001000101110110+3 == 10001000101110112
10001000101110110+4 == 10001000101110114
10001000101110110+5 == 10001000101110116

Все они верны;так что вы можете проверить некоторые библиотеки BigNumber, чтобы ваш код работал.

0 голосов
/ 06 марта 2012

Я могу ошибаться в этом, но это может быть ошибкой точности, возникающей из-за того, что числа JS представлены в виде двойных чисел IEEE, а число, которое вы описываете, настолько велико, что может фактически оказаться вне диапазонацелочисленных значений, представимых точно с IEEE удваивается.Если это так, вам, вероятно, следует подумать о том, чтобы ваша функция возвращала строковое представление двоичного представления, а не числовое представление 1 и 0.

Согласно этому более раннему ответу ,наибольшее целое число, представимое точно двойником IEEE (без пробелов в представимых целых числах), составляет 2 ^ 53, что составляет около 10 ^ 14.Номер, с которым вы описываете ошибку, имеет более 14 цифр, поэтому я подозреваю, что это проблема.

Надеюсь, это поможет!

...