在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
检查和某种查找表吗?
我喜欢你的第一个想法(你试过吗?
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