在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