【问题标题】:How can I efficiently tell if a value I store is within a TypedArray's range?如何有效地判断我存储的值是否在 TypedArray 的范围内?
【发布时间】:2019-10-19 01:03:23
【问题描述】:

在 Chrome(可能还有其他浏览器)中,当我将值存储到超出其范围的 TypedArray 时,它会被截断:

const arr = new Uint16Array(1);
arr[0] = 100000;
console.log(arr[0]); // logs 34464

我的设计允许用户提供任何 TypedArray 类型,并且我希望能够检测到何时会发生这种溢出并抛出 RangeError 而不是截断数据:

const arr: T = getArraySomehow(); // T implements TypedArray
const val: number = getValueSomehow();
if (valOverflows(val, arr)) {
    throw new RangeError('Value overflow');
}
arr[getIndexSomehow()] = val;

实现/内联valOverflows() 的最佳方式是什么?

  • 我是否真的应该尝试存储该值并查看是否可以原封不动地取回它?这可能适用于整数数组,但不适用于浮点数组(因为这里的损失可能只是精度损失),其他方法可能更快。
  • TypedArray 原型上是否有提供最小值和最大值的秘密/实验方法,或者有导致溢出信号的标志?
  • 我应该只使用instanceof 检查和某种查找表吗?

【问题讨论】:

  • 我所知道的最好的将涉及BYTES_PER_ELEMENT,但它不允许检查有符号和无符号元素。除了写入数组之外,我认为查找表 (Map) 可能是最合适的解决方案。
  • 你的设计有点奇怪。为什么事先不知道要存储的值的范围,为什么允许用户传递任意数组类型?我建议您的函数的调用者应该将 valOverflows 函数与数组一起传递,让他们负责两者。如果 () => false 不提供检查功能,请使用它们作为后备。

标签: javascript typescript integer-overflow


【解决方案1】:

我喜欢你的第一个想法(你试过了吗?)。

const compare = (val, type) => {
  const arr = new type(1)
  arr[0] = val
  const same = arr[0] === val
  console.log(val, arr[0], same)
  return same
}

var value = 300
compare(value, Int16Array)
compare(value, Uint8Array)
compare(value, Uint16Array)
value = 2**32
compare(value, Uint32Array)
value -= 1
compare(value, Uint32Array)

这只是将值与特定数组类型上设置的值的实例进行比较。


现在正如您所提到的,这不适用于浮点数,因为该值很可能在范围内,只是精度有问题。对于浮点数,您可以使用地图并比较硬编码的范围限制。但我想如果你这样做,你还不如为所有类型使用地图。

const ranges = {
  [Uint8Array.name]: {
    min: 0,
    max: 255
  },
  [Float32Array.name]: {
    min: 1.2e-38,
    max: 3.4e38
  }
}

const compare = (val, type) => {
  const { min, max } = ranges[type.name]
  return val >= min && val <= max
}

console.log(compare(100, Float32Array))
console.log(compare(3.4e38, Float32Array))
console.log(compare(3.5e38, Float32Array))
console.log(compare(255, Uint8Array))
console.log(compare(256, Uint8Array))

范围可以在这里找到:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-15
    • 2016-11-07
    • 1970-01-01
    • 2016-01-04
    • 1970-01-01
    相关资源
    最近更新 更多