Функции или методы Javascript, которые принимают основание?

Эти функции принимают radix в качестве аргумента:

  • num.toString(radix);
  • parseInt("123", radix);

Есть ли какая-либо другая функция или метод, который принимает radix (основание счисления), потому что я хотел бы использовать что-то вроде parseFloat("1A.B4",radix).

Но поскольку я не думаю, что их много, пожалуйста, назовите любой из них, если вы знаете, это может быть полезно, спасибо.

Изменить: Да, parseFloat("1A.B4",16) должно быть 26.703125. Если вы посмотрите на num.toString(radix), он поддерживает базы от 2 до 36.

В консоли Firefox (333.444).toString(36) равно "99.fzf9i56mi"


person user3761570    schedule 13.09.2017    source источник
comment
Что вообще означает 1A.B4?   -  person Nick    schedule 14.09.2017
comment
@NickA Я считаю, что это будет шестнадцатеричный эквивалент 26.703125 (26 и 180/256)   -  person Patrick Roberts    schedule 14.09.2017
comment
@Pat, по-видимому, должен точно знать, что ищет OP. Поскольку они указали проценты в шестнадцатеричном формате parseFloat. Тем не менее, запросил список всех методов, использующих систему счисления.   -  person Nick    schedule 14.09.2017
comment
Если вы просто хотите проанализировать шестнадцатеричное число с плавающей запятой, вы можете создать функцию, которая делает что-то вроде этого: parseInt( '1A', 16 ) + parseInt( 'B4', 16 )*Math.pow( 16, -'B4'.length)   -  person Paul    schedule 14.09.2017


Ответы (3)


Обобщив @Paulpro comment в функцию, вы можете переопределить parseFloat() следующим образом:

parseFloat = function parseFloat (string, radix = 10) {
  if (radix == 10) {
    return this(string)
  }
  
  const [iString, fString = '0'] = string.split('.')
  const iNumber = parseInt(iString, radix)
  const fNumber = parseInt(fString, radix)
  const fLength = Math.max(fNumber.toString(radix).length, fString.length)
  const sign = Infinity / iNumber === Infinity ? 1 : -1
  
  return iNumber + sign * fNumber / radix ** fLength
}.bind(parseFloat)

console.log(parseFloat('1A.B4', 16))
console.log(parseFloat(0.05.toString(16), 16))
console.log(parseFloat('7', 16))
console.log(parseFloat('-0.8', 16))

Я не уверен, что это то, что вы искали, но я надеюсь, что это поможет.

person Patrick Roberts    schedule 13.09.2017
comment
Я думаю, что есть проблема, если ввод имеет 0 сразу после ., например. parseFloat(0.05.toString(16), 16) дает 0,8, а не 0,05. - person skirtle; 14.09.2017
comment
Я знаю, что это глупая территория, но если вы попробуете что-то вроде var number = '0.' + (new Array(100)).join('1234567890');, вы получите строку, состоящую из '0.1234567890123...' и примерно 1000 цифр. Собственный parseFloat может справиться с этим в базе 10, но с использованием вашего текущего кода он переполнит Math.pow для базы 16. Я не уверен в деталях, но, возможно, какое-то усечение строки исправит это? - person skirtle; 14.09.2017
comment
@skirtle, имеющая дело с нелепым крайним случаем, подобным этому, излишне раздует реализацию, а также приведет к потере точности для более распространенных вариантов использования, поэтому я бы рекомендовал обрезать строку до меньшего количества цифр, прежде чем передавать ее в качестве входных данных. - person Patrick Roberts; 14.09.2017
comment
Я считаю, что parseFloat('7', 16) в настоящее время терпит неудачу, как и любое другое число, в котором нет .. - person skirtle; 14.09.2017
comment
Теперь, что я могу обратиться. Исправлено. - person Patrick Roberts; 14.09.2017
comment
Возможно, добавить поддержку отрицательных чисел? parseFloat('-0.8', 16) в настоящее время выходит как положительный 0.5. - person skirtle; 14.09.2017
comment
Вау, я не знал, что вы можете вызвать это () - person user3761570; 14.09.2017
comment
@user3761570 user3761570, если вы привязываете функцию к контексту, то обязательно - person Patrick Roberts; 14.09.2017

Это моя попытка версии parseFloat, которая поддерживает систему счисления. Я старался избегать использования Math.pow, потому что опасался потенциальных проблем, если бит после . был очень длинным.

function parseFloatRadix(num, radix) {
    var parts = num.trim().split('.'),
        integerStr = parts[0] || '0',
        integer = parseInt(integerStr, radix),
        fractionStr = parts[1] || '0',
        index = fractionStr.length - 1,
        fraction = 0,
        sign = integerStr.charAt(0) === '-' ? -1 : 1;

    for ( ; index >= 0 ; --index) {
        fraction += sign * parseInt(fractionStr.charAt(index), radix);
        fraction /= radix;
    }

    return integer + fraction;
}

[
  12.34,
  12345678,
  0.3,
  0.1 + 0.2, // Note this is not 0.3
  0.01,
  0.001,
  0.0001,
  Math.PI,
  0,
  -1,
  -100,
  -1.5,
  -0.5
].forEach(function(num) {
    var hex = num.toString(16),
        binary = num.toString(2);

    console.log(
        num,
        hex,
        binary,
        parseFloatRadix(hex, 16),
        parseFloatRadix(binary, 2)
    );
});

person skirtle    schedule 13.09.2017
comment
FYI Math.pow( 16, -length ) даст точный ответ для целых чисел от length до 268, поскольку это будет степень двойки, которую легко сохранить в типе чисел с плавающей запятой JavaScript. За пределами этой длины окончательный ответ все равно не может быть представлен в виде числа JavaScript, поэтому нет проблем с использованием Math.pow для этого. - person Paul; 14.09.2017
comment
Могут быть ошибки с плавающей запятой для многозначных чисел в основаниях, которые не являются степенями двойки, но я не верю, что цикл решит эти проблемы. - person Paul; 14.09.2017
comment
@Paulpro На самом деле меня беспокоила не точность этих дополнительных цифр, а гарантия того, что они не взорвут весь алгоритм. Если после . есть 270 цифр (я знаю, это безумие), мой подход все равно должен давать разумное приближение к наиболее значащим цифрам, тогда как вычисление Math.pow даст вам только 0 или Infinity в зависимости от того, включаете ли вы -. Оглядываясь назад, возможно, было бы проще просто обрезать ввод, если вместо этого он будет сумасшедшим. - person skirtle; 14.09.2017

Я хотел бы использовать что-то вроде parseFloat("1A.B4", radix)

Конечно. Хотя в parseFloat() нет поддержки системы счисления, мы можем легко создать собственную функцию parseFloatRadix() следующим образом:

function parseFloatRadix(num, radix) {
  return parseInt(num.replace('.', ''), radix) /
    Math.pow(radix, (num.split('.')[1] || '').length)
}

Этот ответ stackowerflow содержит более подробную информацию. Демонстрационный код ниже.

function parseFloatRadix(num, radix) {
  return parseInt(num.replace('.', ''), radix) /
      Math.pow(radix, (num.split('.')[1] || '').length)
}

test('1A.B4', 16, 26.703125);
test('99.fzf9i56mi', 36, 333.444);

function test(num, radix, expected){
  let result = parseFloatRadix(num, radix);
  console.log(num + ' (base ' + radix +') --> ' + result + 
    (result === expected ? ' (OK)' : ' (Expected ' + expected + ')'));
}

person Tomas Langkaas    schedule 04.11.2019