如何有效判断我存储的值是否在TypedArray的范围内?

问题描述 投票:1回答:1

在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检查和某种查找表吗?
javascript typescript integer-overflow
1个回答
0
投票

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

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

© www.soinside.com 2019 - 2024. All rights reserved.