База 36 в BigInt? - PullRequest
       19

База 36 в BigInt?

6 голосов
/ 12 апреля 2019

Предположим, я хочу преобразовать строку в кодировке base-36 в BigInt, я могу сделать это:

BigInt(parseInt(x,36))

Но что, если моя строка превышает то, что может безопасно вписаться в число ? например,

parseInt('zzzzzzzzzzzzz',36)

Тогда я начинаю терять точность.

Есть ли какие-либо методы для синтаксического анализа непосредственно в BigInt?

Ответы [ 2 ]

5 голосов
/ 12 апреля 2019

Вы можете преобразовать число в тип bigint.

function convert(value, radix) {
    return [...value.toString()]
        .reduce((r, v) => r * BigInt(radix) + BigInt(parseInt(v, radix)), 0n);
}

console.log(convert('zzzzzzzzzzzzz', 36).toString());

С большими кусками, как, например, с десятью (одиннадцать возвращают ложный результат).

function convert(value, radix) { // value: string
    var size = 10,
        factor = BigInt(radix ** size),
        i = value.length % size || size,
        parts = [value.slice(0, i)];

    while (i < value.length) parts.push(value.slice(i, i += size));

    return parts.reduce((r, v) => r * factor + BigInt(parseInt(v, radix)), 0n);
}

console.log(convert('zzzzzzzzzzzzz', 36).toString());
4 голосов
/ 12 апреля 2019

Не уверен, есть ли встроенный, но от Base-X до BigInt довольно легко реализовать:

function parseBigInt(
  numberString,
  keyspace = "0123456789abcdefghijklmnopqrstuvwxyz",
) {
  let result = 0n;
  const keyspaceLength = BigInt(keyspace.length);
  for (let i = numberString.length - 1; i >= 0; i--) {
    const value = keyspace.indexOf(numberString[i]);
    if (value === -1) throw new Error("invalid string");
    result = result * keyspaceLength + BigInt(value);
  }
  return result;
}

console.log(parseInt("zzzzzzz", 36));
console.log(parseBigInt("zzzzzzz"));
console.log(parseBigInt("zzzzzzzzzzzzzzzzzzzzzzzzzz"));

выходы

78364164095
78364164095n
29098125988731506183153025616435306561535n

Значение по умолчанию keyspace эквивалентно тому, что использует parseInt с базой 36, но если вам нужно что-то еще, опция есть. :)

...