在JavaScript中使用Atomics和Float32Array

时间:2016-06-24 22:22:06

标签: javascript atomic typed-arrays

Atomics.store/load方法(以及其他方法?看起来不太好)不支持Float32Array。 我读到,这与以下事实是一致的:由于兼容性原因,它也不支持Float64Array(有些计算机不支持它)。

除了我认为这是愚蠢的事实之外,这是否也意味着我必须将我想要使用的每个浮点数转换为unsigned int?

这不仅会导致丑陋的代码,还会使代码变慢。

E.g:

let a = new Float32Array(1); // Want the result here

Atomics.store(a, 0, 0.5); // Oops, can't use Float32Array

let b = new Float32Array(1); // Want the result here

let uint = new Uint32Array(1);
let float = new Float32Array(uint.buffer);

float[0] = 0.5;

Atomics.store(b, 0, uint[0]);

2 个答案:

答案 0 :(得分:3)

正如您所发现的那样,Atomics方法doesn't support floating point values作为参数:

  

Atomics.store(typedArray,index,value)

     

typedArray
  共享的整数类型数组。 Int8Array,Uint8Array,Int16Array,Uint16Array,Int32Array之一,
  或Uint32Array。

您可以像在发布的示例代码中那样从底层缓冲区读取IEEE754表示为整数

var buffer = new ArrayBuffer(4);         // common buffer
var float32 = new Float32Array(buffer);  // floating point
var uint32 = new Uint32Array(buffer);    // IEEE754 representation

float32[0] = 0.5;
console.log("0x" + uint32[0].toString(16));

uint32[0] = 0x3f000000;   /// IEEE754 32-bit representation of 0.5
console.log(float32[0]);

如果准确性不重要,您可以使用固定数字。准确性当然取决于幅度。

存储时放大:

Atomics.store(a, 0, Math.round(0.5 * 100)); // 0.5 -> 50 (max two decimals with 100)

回读并缩小规模:

value = Atomics.load(a, 0) * 0.01;          // 50 -> 0.5

答案 1 :(得分:0)

另一个答案对我没有多大帮助,我花了一段时间才找到解决方案,但这是我解决同一问题的方法:

var data = new SharedArrayBuffer(LEN * 8);
var data_float = new Float32Array(data);
var data_int = new Uint32Array(data);
data_float[0] = 2.3; //some pre-existing data

var tmp = new ArrayBuffer(8);
var tmp_float = new Float32Array(tmp);
var tmp_int = new Uint32Array(tmp);

tmp_int[0] = Atomics.load(data_int, 0);
tmp_float[0] += 1.1; //some math
Atomics.store(data_int, 0, tmp_int[0]);

console.log(data_float[0]);