【问题标题】:Javascript functions or methods that take radix?采用基数的 Javascript 函数或方法?
【发布时间】:2019-11-06 20:47:52
【问题描述】:

这些函数将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"

【问题讨论】:

  • 1A.B4 到底是什么意思?
  • @NickA 我相信这将是 26.703125(26 和 180/256)的十六进制等价物
  • @Pat 大概需要知道 OP 到底在寻找什么。因为他们已经指定了对十六进制 parseFloat 的兴趣。但要求提供所有“采用基数的方法”的列表
  • 如果你只想解析一个十六进制浮点数,你可以创建一个函数来做这样的事情:parseInt( '1A', 16 ) + parseInt( 'B4', 16 )*Math.pow( 16, -'B4'.length)

标签: javascript parsing numbers radix


【解决方案1】:

@Paulpro's 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))

我不确定这是否是您正在寻找的,但我希望它会有所帮助。

【讨论】:

  • 我认为如果输入在 . 之后直接有一个 0 会有问题,例如parseFloat(0.05.toString(16), 16) 给出 0.8 而不是 0.05。
  • 我知道这是一个愚蠢的领域,但如果你尝试像var number = '0.' + (new Array(100)).join('1234567890'); 这样的东西,你会得到一个'0.1234567890123...' 和大约1000 位数字的字符串。本机 parseFloat 可以在基数 10 中处理此问题,但使用您当前的代码会溢出基数为 16 的 Math.pow。我不确定具体细节,但字符串上的某种截断可能会解决这个问题?
  • @skirtle 处理这样一个荒谬的边缘情况会不必要地使实现膨胀,并且还会导致更常见用例的精度损失,所以我的建议是将字符串截断为更少的数字在将其作为输入传递之前。
  • 我相信parseFloat('7', 16) 目前失败了,其他没有. 的号码也是如此。
  • 现在,我可以解决了。固定。
【解决方案2】:

这是我对支持基数的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)
    );
});

【讨论】:

  • 仅供参考 Math.pow( 16, -length ) 将给出整数 length268 的准确答案,因为它是 2 的幂,它很容易存储在 JavaScript 的浮点数类型中。超过这个长度,最终答案无论如何都不能用 JavaScript 数字表示,所以使用Math.pow 没有问题。
  • 基数不是 2 的幂的多位数字可能会出现浮点错误,但我认为循环不会解决这些问题。
  • @Paulpro 我真正关心的并不是那些额外数字的准确性,而是确保它们不会破坏整个算法。如果. 之后有 270 位数字(我知道,疯了),我的方法仍然应该给出最高有效数字的合理近似值,而计算 Math.pow 只会给你 0Infinity 取决于你是否包括-。事后看来,如果输入很长,那么截断输入可能会更容易。
【解决方案3】:

我想使用类似parseFloat("1A.B4", radix)

当然。虽然parseFloat() 中不支持基数,但我们可以像这样轻松构建自己的parseFloatRadix() 函数:

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

This stackowerflow answer 提供更多详细信息。演示代码如下。

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 + ')'));
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-03-11
    • 2016-02-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-23
    • 1970-01-01
    • 2020-11-07
    相关资源
    最近更新 更多